1#ifndef DICE_HASH_WYHASH_H 
    2#define DICE_HASH_WYHASH_H 
   13#ifndef wyhash_final_version_3 
   14#define wyhash_final_version_3 
   20#define WYHASH_CONDOM 2  
   23#ifndef WYHASH_32BIT_MUM 
   26#define WYHASH_32BIT_MUM 0 
   32#if defined(_MSC_VER) && defined(_M_X64) 
   34#pragma intrinsic(_umul128) 
   38#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) 
   39#define _likely_(x) __builtin_expect(x, 1) 
   40#define _unlikely_(x) __builtin_expect(x, 0) 
   42#define _likely_(x) (x) 
   43#define _unlikely_(x) (x) 
   45namespace dice::hash::wyhash {
 
   47    static inline uint64_t _wyrot(uint64_t x) { 
return (x >> 32) | (x << 32); }
 
   48    static inline void _wymum(uint64_t *A, uint64_t *B) {
 
   50        uint64_t hh = (*A >> 32) * (*B >> 32), hl = (*A >> 32) * (uint32_t) *B, lh = (uint32_t) *A * (*B >> 32), ll = (uint64_t) (uint32_t) *A * (uint32_t) *B;
 
   51#if (WYHASH_CONDOM > 1) 
   52        *A ^= _wyrot(hl) ^ hh;
 
   53        *B ^= _wyrot(lh) ^ ll;
 
   58#elif defined(__SIZEOF_INT128__) 
   61#if (WYHASH_CONDOM > 1) 
   63        *B ^= (uint64_t) (r >> 64);
 
   66        *B = (uint64_t) (r >> 64);
 
   68#elif defined(_MSC_VER) && defined(_M_X64) 
   69#if (WYHASH_CONDOM > 1) 
   71        a = _umul128(*A, *B, &b);
 
   75        *A = _umul128(*A, *B, B);
 
   78        uint64_t ha = *A >> 32, hb = *B >> 32, la = (uint32_t) *A, lb = (uint32_t) *B, hi, lo;
 
   79        uint64_t rh = ha * hb, rm0 = ha * lb, rm1 = hb * la, rl = la * lb, t = rl + (rm0 << 32), c = t < rl;
 
   82        hi = rh + (rm0 >> 32) + (rm1 >> 32) + c;
 
   83#if (WYHASH_CONDOM > 1) 
   94    static inline uint64_t _wymix(uint64_t A, uint64_t B) {
 
  100#ifndef WYHASH_LITTLE_ENDIAN 
  101#if defined(_WIN32) || defined(__LITTLE_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) 
  102#define WYHASH_LITTLE_ENDIAN 1 
  103#elif defined(__BIG_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 
  104#define WYHASH_LITTLE_ENDIAN 0 
  106#warning could not determine endianness! Falling back to little endian. 
  107#define WYHASH_LITTLE_ENDIAN 1 
  112#if (WYHASH_LITTLE_ENDIAN) 
  113    static inline uint64_t _wyr8(
const uint8_t *p) {
 
  118    static inline uint64_t _wyr4(
const uint8_t *p) {
 
  123#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) 
  124    static inline uint64_t _wyr8(
const uint8_t *p) {
 
  127        return __builtin_bswap64(v);
 
  129    static inline uint64_t _wyr4(
const uint8_t *p) {
 
  132        return __builtin_bswap32(v);
 
  134#elif defined(_MSC_VER) 
  135    static inline uint64_t _wyr8(
const uint8_t *p) {
 
  138        return _byteswap_uint64(v);
 
  140    static inline uint64_t _wyr4(
const uint8_t *p) {
 
  143        return _byteswap_ulong(v);
 
  146    static inline uint64_t _wyr8(
const uint8_t *p) {
 
  149        return (((v >> 56) & 0xff) | ((v >> 40) & 0xff00) | ((v >> 24) & 0xff0000) | ((v >> 8) & 0xff000000) | ((v << 8) & 0xff00000000) | ((v << 24) & 0xff0000000000) | ((v << 40) & 0xff000000000000) | ((v << 56) & 0xff00000000000000));
 
  151    static inline uint64_t _wyr4(
const uint8_t *p) {
 
  154        return (((v >> 24) & 0xff) | ((v >> 8) & 0xff00) | ((v << 8) & 0xff0000) | ((v << 24) & 0xff000000));
 
  157    static inline uint64_t _wyr3(
const uint8_t *p, 
size_t k) { 
return (((uint64_t) p[0]) << 16) | (((uint64_t) p[k >> 1]) << 8) | p[k - 1]; }
 
  159    static inline uint64_t wyhash(
const void *key, 
size_t len, uint64_t seed, 
const uint64_t *secret) {
 
  160        const uint8_t *p = (
const uint8_t *) key;
 
  163        if (_likely_(len <= 16)) {
 
  164            if (_likely_(len >= 4)) {
 
  165                a = (_wyr4(p) << 32) | _wyr4(p + ((len >> 3) << 2));
 
  166                b = (_wyr4(p + len - 4) << 32) | _wyr4(p + len - 4 - ((len >> 3) << 2));
 
  167            } 
else if (_likely_(len > 0)) {
 
  174            if (_unlikely_(i > 48)) {
 
  175                uint64_t see1 = seed, see2 = seed;
 
  177                    seed = _wymix(_wyr8(p) ^ secret[1], _wyr8(p + 8) ^ seed);
 
  178                    see1 = _wymix(_wyr8(p + 16) ^ secret[2], _wyr8(p + 24) ^ see1);
 
  179                    see2 = _wymix(_wyr8(p + 32) ^ secret[3], _wyr8(p + 40) ^ see2);
 
  182                } 
while (_likely_(i > 48));
 
  185            while (_unlikely_(i > 16)) {
 
  186                seed = _wymix(_wyr8(p) ^ secret[1], _wyr8(p + 8) ^ seed);
 
  190            a = _wyr8(p + i - 16);
 
  191            b = _wyr8(p + i - 8);
 
  193        return _wymix(secret[1] ^ len, _wymix(a ^ secret[1], b ^ seed));
 
  197    static constexpr const uint64_t _wyp[4] = {0xa0761d6478bd642full, 0xe7037ed1a0b428dbull, 0x8ebc6af09c88c6e3ull, 0x589965cc75374cc3ull};
 
  200    static inline uint64_t wyhash64(uint64_t A, uint64_t B) {
 
  201        A ^= 0xa0761d6478bd642full;
 
  202        B ^= 0xe7037ed1a0b428dbull;
 
  204        return _wymix(A ^ 0xa0761d6478bd642full, B ^ 0xe7037ed1a0b428dbull);
 
  208    static inline uint64_t wyrand(uint64_t *seed) {
 
  209        *seed += 0xa0761d6478bd642full;
 
  210        return _wymix(*seed, *seed ^ 0xe7037ed1a0b428dbull);
 
  214    static inline double wy2u01(uint64_t r) {
 
  215        const double _wynorm = 1.0 / (1ull << 52);
 
  216        return (r >> 12) * _wynorm;
 
  220    static inline double wy2gau(uint64_t r) {
 
  221        const double _wynorm = 1.0 / (1ull << 20);
 
  222        return ((r & 0x1fffff) + ((r >> 21) & 0x1fffff) + ((r >> 42) & 0x1fffff)) * _wynorm - 3.0;
 
  225#if (!WYHASH_32BIT_MUM) 
  227    static inline uint64_t wy2u0k(uint64_t r, uint64_t k) {
 
  234    static inline void make_secret(uint64_t seed, uint64_t *secret) {
 
  235        uint8_t c[] = {15, 23, 27, 29, 30, 39, 43, 45, 46, 51, 53, 54, 57, 58, 60, 71, 75, 77, 78, 83, 85, 86, 89, 90, 92, 99, 101, 102, 105, 106, 108, 113, 114, 116, 120, 135, 139, 141, 142, 147, 149, 150, 153, 154, 156, 163, 165, 166, 169, 170, 172, 177, 178, 180, 184, 195, 197, 198, 201, 202, 204, 209, 210, 212, 216, 225, 226, 228, 232, 240};
 
  236        for (
size_t i = 0; i < 4; i++) {
 
  241                for (
size_t j = 0; j < 64; j += 8) secret[i] |= ((uint64_t) c[wyrand(&seed) % 
sizeof(c)]) << j;
 
  242                if (secret[i] % 2 == 0) {
 
  246                for (
size_t j = 0; j < i; j++) {
 
  247#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) 
  248                    if (__builtin_popcountll(secret[j] ^ secret[i]) != 32) {
 
  252#elif defined(_MSC_VER) && defined(_M_X64) 
  253                    if (_mm_popcnt_u64(secret[j] ^ secret[i]) != 32) {
 
  259                    uint64_t x = secret[j] ^ secret[i];
 
  260                    x -= (x >> 1) & 0x5555555555555555;
 
  261                    x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
 
  262                    x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f;
 
  263                    x = (x * 0x0101010101010101) >> 56;