src/edh/splitmix64/lib.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../util/consts/lib.hpp" | ||
| 4 | |||
| 5 | namespace tifa_libs { | ||
| 6 | |||
| 7 | class hash_splitmix64 { | ||
| 8 | static inline u64 seed = 114514; | ||
| 9 | 427436640 | static CEXP u64 splitmix64(u64 x) NE { | |
| 10 | 427436640 | x += 0x9e3779b97f4a7c15; | |
| 11 | 427436640 | x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; | |
| 12 | 427436640 | x = (x ^ (x >> 27)) * 0x94d049bb133111eb; | |
| 13 | 427436640 | return x ^ (x >> 31); | |
| 14 | } | ||
| 15 | 143197067 | static CEXP u64 append(u64 x, u64 y) NE { return x ^ (y >> 1) ^ ((y & 1) << 63); } | |
| 16 | |||
| 17 | public: | ||
| 18 | 326 | CEXPE hash_splitmix64(u64 s = TIME) NE { set_seed(s); } | |
| 19 | |||
| 20 | 17 | static void set_seed() NE { seed = (u64)std::chrono::steady_clock::now().time_since_epoch().count(); } | |
| 21 | 326 | static CEXP void set_seed(u64 s) NE { seed = s; } | |
| 22 | 427436640 | u64 operator()(u64 x) CNE { return splitmix64(x + seed); } | |
| 23 | template <class T, class U> | ||
| 24 | 143197067 | u64 operator()(std::pair<T, U> CR p) CNE { return append((*this)(p.first), (*this)(p.second)); } | |
| 25 | template <class... Ts> | ||
| 26 | u64 operator()(std::tuple<Ts...> CR tp) CNE { | ||
| 27 | u64 ret = 0; | ||
| 28 | std::apply([&](Ts CR... targs) NE { ((ret = append(ret, (*this)(targs))), ...); }, tp); | ||
| 29 | return ret; | ||
| 30 | } | ||
| 31 | template <common_range T> | ||
| 32 | u64 operator()(T CR tp) CNE { | ||
| 33 | u64 ret = 0; | ||
| 34 | for (auto&& i : tp) ret = append(ret, (*this)(i)); | ||
| 35 | return ret; | ||
| 36 | } | ||
| 37 | }; | ||
| 38 | |||
| 39 | } // namespace tifa_libs | ||
| 40 |