mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-27 11:06:50 +01:00
feat(HashRange): port HashRange from boost
This commit is contained in:
@@ -10,6 +10,9 @@
|
|||||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||||
// and Contributors.
|
// and Contributors.
|
||||||
//
|
//
|
||||||
|
// HashRange Copyright 2005-2014 Daniel James.
|
||||||
|
// (Extracted from Boost 1.75.0 lib and adapted for poco on 2021-03-31)
|
||||||
|
//
|
||||||
// SPDX-License-Identifier: BSL-1.0
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
//
|
//
|
||||||
|
|
||||||
@@ -19,9 +22,17 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "Poco/Foundation.h"
|
#include "Poco/Foundation.h"
|
||||||
|
#include "Poco/Types.h"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# define POCO_HASH_ROTL32(x, r) _rotl(x,r)
|
||||||
|
#else
|
||||||
|
# define POCO_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
|
|
||||||
|
|
||||||
@@ -99,6 +110,90 @@ inline std::size_t hash(UInt64 n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace Impl {
|
||||||
|
|
||||||
|
|
||||||
|
template <typename SizeT>
|
||||||
|
inline void HashCombine(SizeT& seed, SizeT value)
|
||||||
|
{
|
||||||
|
seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void HashCombine(Poco::UInt32& h1, Poco::UInt32 k1)
|
||||||
|
{
|
||||||
|
const uint32_t c1 = 0xcc9e2d51;
|
||||||
|
const uint32_t c2 = 0x1b873593;
|
||||||
|
|
||||||
|
k1 *= c1;
|
||||||
|
k1 = POCO_HASH_ROTL32(k1,15);
|
||||||
|
k1 *= c2;
|
||||||
|
|
||||||
|
h1 ^= k1;
|
||||||
|
h1 = POCO_HASH_ROTL32(h1,13);
|
||||||
|
h1 = h1*5+0xe6546b64;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(POCO_PTR_IS_64_BIT) && !(defined(__GNUC__) && ULONG_MAX == 0xffffffff)
|
||||||
|
|
||||||
|
|
||||||
|
inline void HashCombine(Poco::UInt64& h, Poco::UInt64 k)
|
||||||
|
{
|
||||||
|
const Poco::UInt64 m = UINT64_C(0xc6a4a7935bd1e995);
|
||||||
|
const int r = 47;
|
||||||
|
|
||||||
|
k *= m;
|
||||||
|
k ^= k >> r;
|
||||||
|
k *= m;
|
||||||
|
|
||||||
|
h ^= k;
|
||||||
|
h *= m;
|
||||||
|
|
||||||
|
// Completely arbitrary number, to
|
||||||
|
// prevent zeros from hashing to 0.
|
||||||
|
h += 0xe6546b64;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // POCO_PTR_IS_64_BIT
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Impl
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline void HashCombine(std::size_t& seed, T const& v)
|
||||||
|
{
|
||||||
|
Hash<T> hasher;
|
||||||
|
Impl::HashCombine(seed, hasher(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class It>
|
||||||
|
inline std::size_t HashRange(It first, It last)
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
|
||||||
|
for(; first != last; ++first)
|
||||||
|
{
|
||||||
|
HashCombine<typename std::iterator_traits<It>::value_type>(seed, *first);
|
||||||
|
}
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class It>
|
||||||
|
inline void HashRange(std::size_t& seed, It first, It last)
|
||||||
|
{
|
||||||
|
for(; first != last; ++first)
|
||||||
|
{
|
||||||
|
HashCombine<typename std::iterator_traits<It>::value_type>(seed, *first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user