Skip to content

Commit 2489500

Browse files
committed
mixers.h, math.hpp
1 parent 220c087 commit 2489500

3 files changed

Lines changed: 53 additions & 2 deletions

File tree

cpp-template-utils.pro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ HEADERS += \
2121
$$files(regex/*.hpp, false) \
2222
$$files(string/*.hpp, false) \
2323
$$files(tuple/*.hpp, false) \
24-
$$files(utility/*.h*, false)
24+
$$files(utility/*.h*, false) \
25+
hash/mixers.h

hash/mixers.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
3+
#include <stdint.h>
4+
5+
[[nodiscard]] inline uint64_t mix_moremur(uint64_t x)
6+
{
7+
x ^= x >> 27;
8+
x *= 0x3C79AC492BA7B653ull;
9+
x ^= x >> 33;
10+
x *= 0x1C69B3F74AC4AE35ull;
11+
x ^= x >> 27;
12+
return x;
13+
}

math/math.hpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
#include <stdint.h>
99
#include <math.h>
1010

11+
#ifdef _MSC_VER
12+
#include <intrin.h>
13+
#endif
14+
1115
namespace Math {
1216

1317
template <typename T>
@@ -147,8 +151,41 @@ template <typename ResultType, typename... Args>
147151
return result;
148152
}
149153

150-
[[nodiscard]] inline constexpr uint64_t reduce(uint32_t value, uint32_t range) noexcept {
154+
[[nodiscard]] inline constexpr uint64_t reduce(uint32_t value, uint32_t range) noexcept
155+
{
151156
return ((uint64_t)value * (uint64_t)range) >> 32;
152157
}
153158

159+
inline uint32_t fastmod_u32(uint32_t a, uint64_t M, uint32_t d) noexcept
160+
{
161+
const uint64_t lowbits = M * a;
162+
#if defined(__SIZEOF_INT128__) // GCC / Clang
163+
return (uint32_t)(((__uint128_t)lowbits * d) >> 64);
164+
#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
165+
return (uint32_t)__umulh(lowbits, d);
166+
#else // portable: 32-bit targets
167+
const uint64_t lo = (lowbits & 0xFFFFFFFFull) * d;
168+
const uint64_t hi = (lowbits >> 32) * d;
169+
return (uint32_t)((hi + (lo >> 32)) >> 32);
170+
#endif
171+
}
172+
173+
inline constexpr uint64_t computeM_u32(uint32_t d) noexcept {
174+
return UINT64_C(0xFFFFFFFFFFFFFFFF) / d + 1;
175+
}
176+
177+
class FastMod32
178+
{
179+
const uint64_t M;
180+
const uint32_t d;
181+
public:
182+
inline constexpr FastMod32(uint32_t divisor) noexcept
183+
: M(computeM_u32(divisor)), d(divisor)
184+
{}
185+
inline uint32_t mod(uint32_t a) const noexcept
186+
{
187+
return fastmod_u32(a, M, d);
188+
}
189+
};
190+
154191
} // namespace Math

0 commit comments

Comments
 (0)