20 #ifndef ANTKEEPER_MATH_HASH_PCG_HPP
21 #define ANTKEEPER_MATH_HASH_PCG_HPP
26 #include <type_traits>
33 constexpr T pcg_multiplier = 0;
35 constexpr std::uint8_t pcg_multiplier<std::uint8_t> = 141U;
37 constexpr std::uint16_t pcg_multiplier<std::uint16_t> = 12829U;
39 constexpr std::uint32_t pcg_multiplier<std::uint32_t> = 747796405UL;
41 constexpr std::uint64_t pcg_multiplier<std::uint64_t> = 6364136223846793005ULL;
45 constexpr T pcg_increment = 0;
47 constexpr std::uint8_t pcg_increment<std::uint8_t> = 77U;
49 constexpr std::uint16_t pcg_increment<std::uint16_t> = 47989U;
51 constexpr std::uint32_t pcg_increment<std::uint32_t> = 2891336453UL;
53 constexpr std::uint64_t pcg_increment<std::uint64_t> = 1442695040888963407ULL;
57 constexpr T mcg_multiplier = 0;
59 constexpr std::uint8_t mcg_multiplier<std::uint8_t> = 217U;
61 constexpr std::uint16_t mcg_multiplier<std::uint16_t> = 62169U;
63 constexpr std::uint32_t mcg_multiplier<std::uint32_t> = 277803737UL;
65 constexpr std::uint64_t mcg_multiplier<std::uint64_t> = 12605985483714917081ULL;
69 [[nodiscard]] constexpr T pcg_uint(T x) noexcept
71 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value);
72 static_assert(
sizeof(T) <= 8);
74 x =
x * pcg_multiplier<T> + pcg_increment<T>;
75 x = (
x ^ (
x >> ((
x >> ((
sizeof(T) * 8) - (
sizeof(T) + 1))) + (
sizeof(T) + 1)))) * mcg_multiplier<T>;
76 return x ^ (
x >> ((
sizeof(T) * 16 + 2) / 3));
81 [[nodiscard]]
inline constexpr vector<T, 1> pcg_uvec1(vector<T, 1> x) noexcept
83 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value);
84 static_assert(
sizeof(T) <= 8);
93 [[nodiscard]] constexpr vector<T, 2> pcg_uvec2(vector<T, 2> x) noexcept
95 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value);
96 static_assert(
sizeof(T) <= 8);
98 x =
x * pcg_multiplier<T> + pcg_increment<T>;
100 x[0] +=
x[1] * pcg_multiplier<T>;
101 x[1] +=
x[0] * pcg_multiplier<T>;
103 x[0] ^=
x[0] >> (
sizeof(T) * 4);
104 x[1] ^=
x[1] >> (
sizeof(T) * 4);
106 x[0] +=
x[1] * pcg_multiplier<T>;
107 x[1] +=
x[0] * pcg_multiplier<T>;
109 x[0] ^=
x[0] >> (
sizeof(T) * 4);
110 x[1] ^=
x[1] >> (
sizeof(T) * 4);
117 [[nodiscard]] constexpr vector<T, 3> pcg_uvec3(vector<T, 3> x) noexcept
119 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value);
120 static_assert(
sizeof(T) <= 8);
122 x =
x * pcg_multiplier<T> + pcg_increment<T>;
128 x[0] ^=
x[0] >> (
sizeof(T) * 4);
129 x[1] ^=
x[1] >> (
sizeof(T) * 4);
130 x[2] ^=
x[2] >> (
sizeof(T) * 4);
141 [[nodiscard]] constexpr vector<T, 4> pcg_uvec4(vector<T, 4> x) noexcept
143 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value);
144 static_assert(
sizeof(T) <= 8);
146 x =
x * pcg_multiplier<T> + pcg_increment<T>;
153 x[0] ^=
x[0] >> (
sizeof(T) * 4);
154 x[1] ^=
x[1] >> (
sizeof(T) * 4);
155 x[2] ^=
x[2] >> (
sizeof(T) * 4);
156 x[3] ^=
x[3] >> (
sizeof(T) * 4);
181 [[nodiscard]]
inline constexpr std::uint8_t
pcg(std::uint8_t x) noexcept
183 return pcg_uint<std::uint8_t>(x);
186 [[nodiscard]]
inline constexpr std::uint16_t
pcg(std::uint16_t x) noexcept
188 return pcg_uint<std::uint16_t>(x);
191 [[nodiscard]]
inline constexpr std::uint32_t
pcg(std::uint32_t x) noexcept
193 return pcg_uint<std::uint32_t>(x);
196 [[nodiscard]]
inline constexpr std::uint64_t
pcg(std::uint64_t x) noexcept
198 return pcg_uint<std::uint64_t>(x);
201 [[nodiscard]]
inline constexpr std::uint8_t
pcg(std::int8_t x) noexcept
203 return pcg_uint<std::uint8_t>(
static_cast<std::uint8_t
>(x));
206 [[nodiscard]]
inline constexpr std::uint16_t
pcg(std::int16_t x) noexcept
208 return pcg_uint<std::uint16_t>(
static_cast<std::uint16_t
>(x));
211 [[nodiscard]]
inline constexpr std::uint32_t
pcg(std::int32_t x) noexcept
213 return pcg_uint<std::uint32_t>(
static_cast<std::uint32_t
>(x));
216 [[nodiscard]]
inline constexpr std::uint64_t
pcg(std::int64_t x) noexcept
218 return pcg_uint<std::uint64_t>(
static_cast<std::uint64_t
>(x));
221 [[nodiscard]]
inline constexpr std::uint32_t
pcg(
float x) noexcept
223 return pcg_uint<std::uint32_t>(
static_cast<std::uint32_t
>(x));
226 [[nodiscard]]
inline constexpr std::uint64_t
pcg(
double x) noexcept
228 return pcg_uint<std::uint64_t>(
static_cast<std::uint64_t
>(x));
231 template <
class T, std::
size_t N>
234 static_assert(N > 0 && N < 5,
"PCG hash only supports vectors with 1-4 elements.");
236 if constexpr (N == 1)
238 else if constexpr (N == 2)
240 else if constexpr (N == 3)
constexpr std::uint8_t pcg(std::uint8_t x) noexcept
PCG hash function.
Mathematical functions and data types.