53        constexpr int cpp_version_major = 0;
 
   54        constexpr int cpp_version_minor = 7;
 
   55        constexpr int cpp_version_release = 3;
 
   58    constexpr uint32_t version_number() {
 
   59        return version::cpp_version_major * 10000 + version::cpp_version_minor * 100 + version::cpp_version_release;
 
   73                return (low64 == other.low64 && high64 == other.high64);
 
   77                return (high64 > other.high64 || low64 > other.low64);
 
   81                return (*
this > other || *
this == other);
 
   85                return !(*
this >= other);
 
   89                return !(*
this > other);
 
   93                return !(*
this == other);
 
   96            uint128_t(uint64_t low, uint64_t high) : low64(low), high64(high) {}
 
 
  116#ifndef XXH_CPU_LITTLE_ENDIAN 
  117#define XXH_CPU_LITTLE_ENDIAN 1 
  130#elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2)) 
  137        constexpr int vector_mode = XXH_VECTOR;
 
  140        constexpr int acc_align = 32;
 
  141        using avx2_underlying = __m256i;
 
  142        using sse2_underlying = __m128i;
 
  144        using avx2_underlying = void;
 
  145        using sse2_underlying = __m128i;
 
  146        constexpr int acc_align = 16;
 
  148        using avx2_underlying = void;
 
  149        using sse2_underlying = void;
 
  150        constexpr int acc_align = 8;
 
  157#ifdef XXH_FORCE_INLINE  
  158#undef XXH_FORCE_INLINE 
  165        #pragma warning(disable : 4127) 
  166#define XXH_FORCE_INLINE static __forceinline 
  167#define XXH_NO_INLINE static __declspec(noinline) 
  169#elif defined(__GNUC__)  
  170#define XXH_FORCE_INLINE static inline __attribute__((always_inline)) 
  171#define XXH_NO_INLINE static __attribute__((noinline)) 
  174        #define XXH_FORCE_INLINE static inline 
  175#define XXH_NO_INLINE static 
  182#if defined(XXH_NO_PREFETCH) 
  183        XXH_FORCE_INLINE 
void prefetch(
const void *ptr) {}
 
  184#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) 
  185        XXH_FORCE_INLINE 
void prefetch(
const void *ptr) { _mm_prefetch((
const char *) (ptr), _MM_HINT_T0); }
 
  186#elif defined(__GNUC__) 
  187        XXH_FORCE_INLINE 
void prefetch(
const void *ptr) { __builtin_prefetch((ptr), 0, 3); }
 
  189        XXH_FORCE_INLINE 
void prefetch(
const void *ptr) {}
 
  201#if (defined(__GNUC__) || defined(_MSC_VER)) && defined(__cplusplus) && !defined(XXH_NO_RESTRICT) 
  202#define XXH_RESTRICT __restrict 
  213#if ((defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)) && !defined(XXH_NO_BRANCH_HINTS) 
  214#define XXH_likely(x) __builtin_expect(x, 1) 
  215#define XXH_unlikely(x) __builtin_expect(x, 0) 
  217        #define XXH_likely(x) (x) 
  218#define XXH_unlikely(x) (x) 
  224            static inline uint32_t rotl32(uint32_t x, int32_t r) { 
return _rotl(x, r); }
 
  225            static inline uint64_t rotl64(uint64_t x, int32_t r) { 
return _rotl64(x, r); }
 
  226            static inline uint32_t rotr32(uint32_t x, int32_t r) { 
return _rotr(x, r); }
 
  227            static inline uint64_t rotr64(uint64_t x, int32_t r) { 
return _rotr64(x, r); }
 
  229            static inline uint32_t rotl32(uint32_t x, int32_t r) { 
return ((x << r) | (x >> (32 - r))); }
 
  230            static inline uint64_t rotl64(uint64_t x, int32_t r) { 
return ((x << r) | (x >> (64 - r))); }
 
  231            static inline uint32_t rotr32(uint32_t x, int32_t r) { 
return ((x >> r) | (x << (32 - r))); }
 
  232            static inline uint64_t rotr64(uint64_t x, int32_t r) { 
return ((x >> r) | (x << (64 - r))); }
 
  237            static inline uint32_t swap32(uint32_t x) { 
return _byteswap_ulong(x); }
 
  238            static inline uint64_t swap64(uint64_t x) { 
return _byteswap_uint64(x); }
 
  239#elif defined(__GNUC__) 
  240            static inline uint32_t swap32(uint32_t x) { 
return __builtin_bswap32(x); }
 
  241            static inline uint64_t swap64(uint64_t x) { 
return __builtin_bswap64(x); }
 
  243            static inline uint32_t swap32(uint32_t x) { 
return ((x << 24) & 0xff000000) | ((x << 8) & 0x00ff0000) | ((x >> 8) & 0x0000ff00) | ((x >> 24) & 0x000000ff); }
 
  244            static inline uint64_t swap64(uint64_t x) { 
return ((x << 56) & 0xff00000000000000ULL) | ((x << 40) & 0x00ff000000000000ULL) | ((x << 24) & 0x0000ff0000000000ULL) | ((x << 8) & 0x000000ff00000000ULL) | ((x >> 8) & 0x00000000ff000000ULL) | ((x >> 24) & 0x0000000000ff0000ULL) | ((x >> 40) & 0x000000000000ff00ULL) | ((x >> 56) & 0x00000000000000ffULL); }
 
  248#if defined(_MSC_VER) && defined(_M_IX86) 
  249            XXH_FORCE_INLINE uint64_t mult32to64(uint32_t x, uint32_t y) { 
return __emulu(x, y); }
 
  251            XXH_FORCE_INLINE uint64_t mult32to64(uint32_t x, uint32_t y) { 
return (uint64_t)(uint32_t)(x) * (uint64_t)(uint32_t)(y); }
 
  255#if defined(__GNUC__) && !defined(__clang__) && defined(__i386__) 
  256            __attribute__((__target__(
"no-sse")))
 
  258            static inline uint128_t
 
  259            mult64to128(uint64_t lhs, uint64_t rhs) {
 
  261#if defined(__GNUC__) && !defined(__wasm__) && defined(__SIZEOF_INT128__) || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128) 
  263                __uint128_t product = (__uint128_t) lhs * (__uint128_t) rhs;
 
  264                uint128_t 
const r128 = {(uint64_t)(product), (uint64_t)(product >> 64)};
 
  267#elif defined(_M_X64) || defined(_M_IA64) 
  270#pragma intrinsic(_umul128) 
  272                uint64_t product_high;
 
  273                uint64_t 
const product_low = _umul128(lhs, rhs, &product_high);
 
  274                return uint128_t{product_low, product_high};
 
  276                uint64_t 
const lo_lo = bit_ops::mult32to64(lhs & 0xFFFFFFFF, rhs & 0xFFFFFFFF);
 
  277                uint64_t 
const hi_lo = bit_ops::mult32to64(lhs >> 32, rhs & 0xFFFFFFFF);
 
  278                uint64_t 
const lo_hi = bit_ops::mult32to64(lhs & 0xFFFFFFFF, rhs >> 32);
 
  279                uint64_t 
const hi_hi = bit_ops::mult32to64(lhs >> 32, rhs >> 32);
 
  282                uint64_t 
const cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi;
 
  283                uint64_t 
const upper = (hi_lo >> 32) + (cross >> 32) + hi_hi;
 
  284                uint64_t 
const lower = (cross << 32) | (lo_lo & 0xFFFFFFFF);
 
  286                uint128_t r128 = {lower, upper};
 
  310            using type = uint32_t;
 
 
  315            using type = uint64_t;
 
 
  331            using type = uint64_t;
 
 
  336            using type = intrin::sse2_underlying;
 
 
  341            using type = intrin::avx2_underlying;
 
 
  358            using type = uint32_t;
 
 
  363            using type = uint64_t;
 
 
  373    using hash_t = 
typename typedefs::hash_type<N>::type;
 
  374    using hash32_t = hash_t<32>;
 
  375    using hash64_t = hash_t<64>;
 
  376    using hash128_t = hash_t<128>;
 
  379    using vec_t = 
typename typedefs::vec_type<N>::type;
 
  380    using vec64_t = vec_t<64>;
 
  381    using vec128_t = vec_t<128>;
 
  382    using vec256_t = vec_t<256>;
 
  385    using uint_t = 
typename typedefs::uint_type<N>::type;
 
  398        static inline uint_t<N> rotl(uint_t<N> n, int32_t r) {
 
  399            if constexpr (N == 32) {
 
  400                return intrin::bit_ops::rotl32(n, r);
 
  403            if constexpr (N == 64) {
 
  404                return intrin::bit_ops::rotl64(n, r);
 
  409        static inline uint_t<N> rotr(uint_t<N> n, int32_t r) {
 
  410            if constexpr (N == 32) {
 
  411                return intrin::bit_ops::rotr32(n, r);
 
  414            if constexpr (N == 64) {
 
  415                return intrin::bit_ops::rotr64(n, r);
 
  420        static inline uint_t<N> swap(uint_t<N> n) {
 
  421            if constexpr (N == 32) {
 
  422                return intrin::bit_ops::swap32(n);
 
  425            if constexpr (N == 64) {
 
  426                return intrin::bit_ops::swap64(n);
 
  430        static inline uint64_t mul32to64(uint32_t x, uint32_t y) {
 
  431            return intrin::bit_ops::mult32to64(x, y);
 
  434        static inline uint128_t mul64to128(uint64_t x, uint64_t y) {
 
  435            return intrin::bit_ops::mult64to128(x, y);
 
  438        static inline uint64_t mul128fold64(uint64_t x, uint64_t y) {
 
  439            uint128_t product = mul64to128(x, y);
 
  441            return (product.low64 ^ product.high64);
 
  456        constexpr bool is_little_endian() {
 
  457            return (XXH_CPU_LITTLE_ENDIAN == 1);
 
  466        static inline uint_t<N> read(
const void *memPtr) {
 
  469            memcpy(&val, memPtr, 
sizeof(val));
 
  474        static inline uint_t<N> readLE(
const void *ptr) {
 
  475            if constexpr (is_little_endian()) {
 
  478                return bit_ops::swap<N>(read<N>(ptr));
 
  483        static inline uint_t<N> readBE(
const void *ptr) {
 
  484            if constexpr (is_little_endian()) {
 
  485                return bit_ops::swap<N>(read<N>(ptr));
 
  492        static void writeLE(
void *dst, uint_t<N> v) {
 
  493            if constexpr (!is_little_endian()) {
 
  494                v = bit_ops::swap<N>(v);
 
  497            memcpy(dst, &v, 
sizeof(v));
 
  508        XXH_FORCE_INLINE vec_t<N> loadu(
const vec_t<N> *input) {
 
  509            static_assert(!(N != 128 && N != 256 && N != 64), 
"Invalid template argument passed to xxh::vec_ops::loadu");
 
  511            if constexpr (N == 128) {
 
  512                return _mm_loadu_si128(input);
 
  515            if constexpr (N == 256) {
 
  516                return _mm256_loadu_si256(input);
 
  519            if constexpr (N == 64) {
 
  520                return mem_ops::readLE<64>(input);
 
  527        XXH_FORCE_INLINE vec_t<N> xorv(vec_t<N> a, vec_t<N> b) {
 
  528            static_assert(!(N != 128 && N != 256 && N != 64), 
"Invalid argument passed to xxh::vec_ops::xorv");
 
  530            if constexpr (N == 128) {
 
  531                return _mm_xor_si128(a, b);
 
  534            if constexpr (N == 256) {
 
  535                return _mm256_xor_si256(a, b);
 
  538            if constexpr (N == 64) {
 
  545        XXH_FORCE_INLINE vec_t<N> mul(vec_t<N> a, vec_t<N> b) {
 
  546            static_assert(!(N != 128 && N != 256 && N != 64), 
"Invalid argument passed to xxh::vec_ops::mul");
 
  548            if constexpr (N == 128) {
 
  549                return _mm_mul_epu32(a, b);
 
  552            if constexpr (N == 256) {
 
  553                return _mm256_mul_epu32(a, b);
 
  556            if constexpr (N == 64) {
 
  563        XXH_FORCE_INLINE vec_t<N> add(vec_t<N> a, vec_t<N> b) {
 
  564            static_assert(!(N != 128 && N != 256 && N != 64), 
"Invalid argument passed to xxh::vec_ops::add");
 
  566            if constexpr (N == 128) {
 
  567                return _mm_add_epi64(a, b);
 
  570            if constexpr (N == 256) {
 
  571                return _mm256_add_epi64(a, b);
 
  574            if constexpr (N == 64) {
 
  580        template<
size_t N, u
int8_t S1, u
int8_t S2, u
int8_t S3, u
int8_t S4>
 
  581        XXH_FORCE_INLINE vec_t<N> shuffle(vec_t<N> a) {
 
  582            static_assert(!(N != 128 && N != 256 && N != 64), 
"Invalid argument passed to xxh::vec_ops::shuffle");
 
  584            if constexpr (N == 128) {
 
  585                return _mm_shuffle_epi32(a, _MM_SHUFFLE(S1, S2, S3, S4));
 
  588            if constexpr (N == 256) {
 
  589                return _mm256_shuffle_epi32(a, _MM_SHUFFLE(S1, S2, S3, S4));
 
  592            if constexpr (N == 64) {
 
  599        XXH_FORCE_INLINE vec_t<N> set1(
int a) {
 
  600            static_assert(!(N != 128 && N != 256 && N != 64), 
"Invalid argument passed to xxh::vec_ops::set1");
 
  602            if constexpr (N == 128) {
 
  603                return _mm_set1_epi32(a);
 
  606            if constexpr (N == 256) {
 
  607                return _mm256_set1_epi32(a);
 
  610            if constexpr (N == 64) {
 
  617        XXH_FORCE_INLINE vec_t<N> srli(vec_t<N> n, 
int a) {
 
  618            static_assert(!(N != 128 && N != 256 && N != 64), 
"Invalid argument passed to xxh::vec_ops::srli");
 
  620            if constexpr (N == 128) {
 
  621                return _mm_srli_epi64(n, a);
 
  624            if constexpr (N == 256) {
 
  625                return _mm256_srli_epi64(n, a);
 
  628            if constexpr (N == 64) {
 
  635        XXH_FORCE_INLINE vec_t<N> slli(vec_t<N> n, 
int a) {
 
  636            static_assert(!(N != 128 && N != 256 && N != 64), 
"Invalid argument passed to xxh::vec_ops::slli");
 
  638            if constexpr (N == 128) {
 
  639                return _mm_slli_epi64(n, a);
 
  642            if constexpr (N == 256) {
 
  643                return _mm256_slli_epi64(n, a);
 
  646            if constexpr (N == 64) {
 
  658        using namespace mem_ops;
 
  659        using namespace bit_ops;
 
  666        constexpr static std::array<uint32_t, 5> primes32 = {2654435761U, 2246822519U, 3266489917U, 668265263U, 374761393U};
 
  667        constexpr static std::array<uint64_t, 5> primes64 = {11400714785074694791ULL, 14029467366897019727ULL, 1609587929392839161ULL, 9650029242287828579ULL, 2870177450012600261ULL};
 
  670        constexpr uint_t<N> PRIME(uint64_t n) {
 
  671            if constexpr (N == 32) {
 
  672                return primes32[n - 1];
 
  674                return primes64[n - 1];
 
  684        static inline uint_t<N> round(uint_t<N> seed, uint_t<N> input) {
 
  685            seed += input * PRIME<N>(2);
 
  687            if constexpr (N == 32) {
 
  688                seed = rotl<N>(seed, 13);
 
  690                seed = rotl<N>(seed, 31);
 
  697        static inline uint64_t mergeRound64(hash64_t acc, uint64_t val) {
 
  698            val = round<64>(0, val);
 
  700            acc = acc * PRIME<64>(1) + PRIME<64>(4);
 
  704        static inline void endian_align_sub_mergeround(hash64_t &hash_ret, uint64_t v1, uint64_t v2, uint64_t v3, uint64_t v4) {
 
  705            hash_ret = mergeRound64(hash_ret, v1);
 
  706            hash_ret = mergeRound64(hash_ret, v2);
 
  707            hash_ret = mergeRound64(hash_ret, v3);
 
  708            hash_ret = mergeRound64(hash_ret, v4);
 
  712        static inline hash_t<N> endian_align_sub_ending(hash_t<N> hash_ret, 
const uint8_t *p, 
const uint8_t *bEnd) {
 
  713            if constexpr (N == 32) {
 
  714                while ((p + 4) <= bEnd) {
 
  715                    hash_ret += readLE<32>(p) * PRIME<32>(3);
 
  716                    hash_ret = rotl<32>(hash_ret, 17) * PRIME<32>(4);
 
  721                    hash_ret += (*p) * PRIME<32>(5);
 
  722                    hash_ret = rotl<32>(hash_ret, 11) * PRIME<32>(1);
 
  726                hash_ret ^= hash_ret >> 15;
 
  727                hash_ret *= PRIME<32>(2);
 
  728                hash_ret ^= hash_ret >> 13;
 
  729                hash_ret *= PRIME<32>(3);
 
  730                hash_ret ^= hash_ret >> 16;
 
  734                while (p + 8 <= bEnd) {
 
  735                    const uint64_t k1 = round<64>(0, readLE<64>(p));
 
  738                    hash_ret = rotl<64>(hash_ret, 27) * PRIME<64>(1) + PRIME<64>(4);
 
  743                    hash_ret ^= 
static_cast<uint64_t
>(readLE<32>(p)) * PRIME<64>(1);
 
  744                    hash_ret = rotl<64>(hash_ret, 23) * PRIME<64>(2) + PRIME<64>(3);
 
  749                    hash_ret ^= (*p) * PRIME<64>(5);
 
  750                    hash_ret = rotl<64>(hash_ret, 11) * PRIME<64>(1);
 
  754                hash_ret ^= hash_ret >> 33;
 
  755                hash_ret *= PRIME<64>(2);
 
  756                hash_ret ^= hash_ret >> 29;
 
  757                hash_ret *= PRIME<64>(3);
 
  758                hash_ret ^= hash_ret >> 32;
 
  765        static inline hash_t<N> endian_align(
const void *input, 
size_t len, uint_t<N> seed) {
 
  766            static_assert(!(N != 32 && N != 64), 
"You can only call endian_align in 32 or 64 bit mode.");
 
  768            const uint8_t *p = 
static_cast<const uint8_t *
>(input);
 
  769            const uint8_t *bEnd = p + len;
 
  772            if (len >= (N / 2)) {
 
  773                const uint8_t *
const limit = bEnd - (N / 2);
 
  774                uint_t<N> v1 = seed + PRIME<N>(1) + PRIME<N>(2);
 
  775                uint_t<N> v2 = seed + PRIME<N>(2);
 
  776                uint_t<N> v3 = seed + 0;
 
  777                uint_t<N> v4 = seed - PRIME<N>(1);
 
  780                    v1 = round<N>(v1, readLE<N>(p));
 
  782                    v2 = round<N>(v2, readLE<N>(p));
 
  784                    v3 = round<N>(v3, readLE<N>(p));
 
  786                    v4 = round<N>(v4, readLE<N>(p));
 
  788                } 
while (p <= limit);
 
  790                hash_ret = rotl<N>(v1, 1) + rotl<N>(v2, 7) + rotl<N>(v3, 12) + rotl<N>(v4, 18);
 
  792                if constexpr (N == 64) {
 
  793                    endian_align_sub_mergeround(hash_ret, v1, v2, v3, v4);
 
  796                hash_ret = seed + PRIME<N>(5);
 
  799            hash_ret += 
static_cast<hash_t<N>
>(len);
 
  801            return endian_align_sub_ending<N>(hash_ret, p, bEnd);
 
  811        using namespace vec_ops;
 
  812        using namespace detail;
 
  813        using namespace mem_ops;
 
  814        using namespace bit_ops;
 
  821        enum class acc_width : uint8_t { acc_64bits,
 
  823        enum class vec_mode : uint8_t { scalar = 0,
 
  832        constexpr uint64_t secret_default_size = 192;
 
  833        constexpr uint64_t secret_size_min = 136;
 
  834        constexpr uint64_t secret_consume_rate = 8;
 
  835        constexpr uint64_t stripe_len = 64;
 
  836        constexpr uint64_t acc_nb = 8;
 
  837        constexpr uint64_t prefetch_distance = 384;
 
  838        constexpr uint64_t secret_lastacc_start = 7;
 
  839        constexpr uint64_t secret_mergeaccs_start = 11;
 
  840        constexpr uint64_t midsize_max = 240;
 
  841        constexpr uint64_t midsize_startoffset = 3;
 
  842        constexpr uint64_t midsize_lastoffset = 17;
 
  844        constexpr vec_mode vector_mode = 
static_cast<vec_mode
>(intrin::vector_mode);
 
  845        constexpr uint64_t acc_align = intrin::acc_align;
 
  846        constexpr std::array<uint64_t, 3> vector_bit_width{64, 128, 256};
 
  853        alignas(64) 
constexpr uint8_t default_secret[secret_default_size] = {
 
 1048        constexpr std::array<uint64_t, 8> init_acc = {PRIME<32>(3), PRIME<64>(1), PRIME<64>(2), PRIME<64>(3), PRIME<64>(4), PRIME<32>(2), PRIME<64>(5), PRIME<32>(1)};
 
 1055        static hash_t<64> avalanche(hash_t<64> h64) {
 
 1056            constexpr uint64_t avalanche_mul_prime = 0x165667919E3779F9ULL;
 
 1059            h64 *= avalanche_mul_prime;
 
 1064        template<vec_mode V>
 
 1065        XXH_FORCE_INLINE 
void accumulate_512(
void *XXH_RESTRICT acc, 
const void *XXH_RESTRICT input, 
const void *XXH_RESTRICT secret, acc_width width) {
 
 1066            constexpr uint64_t bits = vector_bit_width[
static_cast<uint8_t
>(V)];
 
 1068            using vec_t = vec_t<bits>;
 
 1070            alignas(
sizeof(vec_t)) vec_t *
const xacc = 
static_cast<vec_t *
>(acc);
 
 1071            const vec_t *
const xinput = 
static_cast<const vec_t *
>(input);
 
 1072            const vec_t *
const xsecret = 
static_cast<const vec_t *
>(secret);
 
 1074            for (
size_t i = 0; i < stripe_len / 
sizeof(vec_t); i++) {
 
 1075                vec_t 
const data_vec = loadu<bits>(xinput + i);
 
 1076                vec_t 
const key_vec = loadu<bits>(xsecret + i);
 
 1077                vec_t 
const data_key = xorv<bits>(data_vec, key_vec);
 
 1078                vec_t product = set1<bits>(0);
 
 1080                if constexpr (V != vec_mode::scalar) {
 
 1081                    vec_t 
const data_key_lo = shuffle<bits, 0, 3, 0, 1>(data_key);
 
 1083                    product = mul<bits>(data_key, data_key_lo);
 
 1085                    if (width == acc_width::acc_128bits) {
 
 1086                        vec_t 
const data_swap = shuffle<bits, 1, 0, 3, 2>(data_vec);
 
 1087                        vec_t 
const sum = add<bits>(xacc[i], data_swap);
 
 1089                        xacc[i] = add<bits>(sum, product);
 
 1091                        vec_t 
const sum = add<bits>(xacc[i], data_vec);
 
 1093                        xacc[i] = add<bits>(sum, product);
 
 1096                    product = mul32to64(data_key & 0xFFFFFFFF, data_key >> 32);
 
 1098                    if (width == acc_width::acc_128bits) {
 
 1099                        xacc[i ^ 1] = add<bits>(xacc[i ^ 1], data_vec);
 
 1101                        xacc[i] = add<bits>(xacc[i], data_vec);
 
 1104                    xacc[i] = add<bits>(xacc[i], product);
 
 1109        template<vec_mode V>
 
 1110        XXH_FORCE_INLINE 
void scramble_acc(
void *XXH_RESTRICT acc, 
const void *XXH_RESTRICT secret) {
 
 1111            constexpr uint64_t bits = vector_bit_width[
static_cast<uint8_t
>(V)];
 
 1114            using vec_t = vec_t<bits>;
 
 1116            alignas(
sizeof(vec_t)) vec_t *
const xacc = (vec_t *) acc;
 
 1117            const vec_t *
const xsecret = (
const vec_t *) secret;
 
 1119            for (
size_t i = 0; i < stripe_len / 
sizeof(vec_t); i++) {
 
 1120                vec_t 
const acc_vec = xacc[i];
 
 1121                vec_t 
const shifted = srli<bits>(acc_vec, 47);
 
 1122                vec_t 
const data_vec = xorv<bits>(acc_vec, shifted);
 
 1123                vec_t 
const key_vec = loadu<bits>(xsecret + i);
 
 1124                vec_t 
const data_key = xorv<bits>(data_vec, key_vec);
 
 1126                if constexpr (V != vec_mode::scalar) {
 
 1127                    vec_t 
const prime32 = set1<bits>(PRIME<32>(1));
 
 1128                    vec_t 
const data_key_hi = shuffle<bits, 0, 3, 0, 1>(data_key);
 
 1129                    vec_t 
const prod_lo = mul<bits>(data_key, prime32);
 
 1130                    vec_t 
const prod_hi = mul<bits>(data_key_hi, prime32);
 
 1132                    xacc[i] = add<bits>(prod_lo, vec_ops::slli<bits>(prod_hi, 32));
 
 1134                    xacc[i] = mul<bits>(data_key, PRIME<32>(1));
 
 1139        XXH_FORCE_INLINE 
void accumulate(uint64_t *XXH_RESTRICT acc, 
const uint8_t *XXH_RESTRICT input, 
const uint8_t *XXH_RESTRICT secret, 
size_t nbStripes, acc_width accWidth) {
 
 1140            for (
size_t n = 0; n < nbStripes; n++) {
 
 1141                const uint8_t *
const in = input + n * stripe_len;
 
 1143                intrin::prefetch(in + prefetch_distance);
 
 1144                accumulate_512<vector_mode>(acc, in, secret + n * secret_consume_rate, accWidth);
 
 1148        XXH_FORCE_INLINE 
void hash_long_internal_loop(uint64_t *XXH_RESTRICT acc, 
const uint8_t *XXH_RESTRICT input, 
size_t len, 
const uint8_t *XXH_RESTRICT secret, 
size_t secretSize, acc_width accWidth) {
 
 1149            size_t const nb_rounds = (secretSize - stripe_len) / secret_consume_rate;
 
 1150            size_t const block_len = stripe_len * nb_rounds;
 
 1151            size_t const nb_blocks = len / block_len;
 
 1153            for (
size_t n = 0; n < nb_blocks; n++) {
 
 1154                accumulate(acc, input + n * block_len, secret, nb_rounds, accWidth);
 
 1155                scramble_acc<vector_mode>(acc, secret + secretSize - stripe_len);
 
 1159            size_t const nbStripes = (len - (block_len * nb_blocks)) / stripe_len;
 
 1161            accumulate(acc, input + nb_blocks * block_len, secret, nbStripes, accWidth);
 
 1164            if (len & (stripe_len - 1)) {
 
 1165                const uint8_t *
const p = input + len - stripe_len;
 
 1167                accumulate_512<vector_mode>(acc, p, secret + secretSize - stripe_len - secret_lastacc_start, accWidth);
 
 1171        XXH_FORCE_INLINE uint64_t mix_2_accs(
const uint64_t *XXH_RESTRICT acc, 
const uint8_t *XXH_RESTRICT secret) {
 
 1172            return mul128fold64(acc[0] ^ readLE<64>(secret), acc[1] ^ readLE<64>(secret + 8));
 
 1175        XXH_FORCE_INLINE uint64_t merge_accs(
const uint64_t *XXH_RESTRICT acc, 
const uint8_t *XXH_RESTRICT secret, uint64_t start) {
 
 1176            uint64_t result64 = start;
 
 1178            result64 += mix_2_accs(acc + 0, secret + 0);
 
 1179            result64 += mix_2_accs(acc + 2, secret + 16);
 
 1180            result64 += mix_2_accs(acc + 4, secret + 32);
 
 1181            result64 += mix_2_accs(acc + 6, secret + 48);
 
 1183            return avalanche(result64);
 
 1186        XXH_FORCE_INLINE 
void init_custom_secret(uint8_t *customSecret, uint64_t seed) {
 
 1187            for (uint64_t i = 0; i < secret_default_size / 16; i++) {
 
 1188                writeLE<64>(customSecret + i * 16, readLE<64>(default_secret + i * 16) + seed);
 
 1189                writeLE<64>(customSecret + i * 16 + 8, readLE<64>(default_secret + i * 16 + 8) - seed);
 
 1194        XXH_FORCE_INLINE hash_t<N> len_1to3(
const uint8_t *input, 
size_t len, 
const uint8_t *secret, uint64_t seed) {
 
 1195            if constexpr (N == 64) {
 
 1196                uint8_t 
const c1 = input[0];
 
 1197                uint8_t 
const c2 = input[len >> 1];
 
 1198                uint8_t 
const c3 = input[len - 1];
 
 1199                uint32_t 
const combined = ((uint32_t) c1 << 16) | (((uint32_t) c2) << 24) | (((uint32_t) c3) << 0) | (((uint32_t) len) << 8);
 
 1200                uint64_t 
const bitflip = (readLE<32>(secret) ^ readLE<32>(secret + 4)) + seed;
 
 1201                uint64_t 
const keyed = (uint64_t) combined ^ bitflip;
 
 1202                uint64_t 
const mixed = keyed * PRIME<64>(1);
 
 1204                return avalanche(mixed);
 
 1206                uint8_t 
const c1 = input[0];
 
 1207                uint8_t 
const c2 = input[len >> 1];
 
 1208                uint8_t 
const c3 = input[len - 1];
 
 1209                uint32_t 
const combinedl = ((uint32_t) c1 << 16) + (((uint32_t) c2) << 24) + (((uint32_t) c3) << 0) + (((uint32_t) len) << 8);
 
 1210                uint32_t 
const combinedh = rotl<32>(swap<32>(combinedl), 13);
 
 1211                uint64_t 
const bitflipl = (readLE<32>(secret) ^ readLE<32>(secret + 4)) + seed;
 
 1212                uint64_t 
const bitfliph = (readLE<32>(secret + 8) ^ readLE<32>(secret + 12)) - seed;
 
 1213                uint64_t 
const keyed_lo = (uint64_t) combinedl ^ bitflipl;
 
 1214                uint64_t 
const keyed_hi = (uint64_t) combinedh ^ bitfliph;
 
 1215                uint64_t 
const mixedl = keyed_lo * PRIME<64>(1);
 
 1216                uint64_t 
const mixedh = keyed_hi * PRIME<64>(5);
 
 1217                hash128_t 
const h128 = {avalanche(mixedl), avalanche(mixedh)};
 
 1224        XXH_FORCE_INLINE hash_t<N> len_4to8(
const uint8_t *input, 
size_t len, 
const uint8_t *secret, uint64_t seed) {
 
 1225            constexpr uint64_t mix_constant = 0x9FB21C651E98DF25ULL;
 
 1227            seed ^= (uint64_t) swap<32>((uint32_t) seed) << 32;
 
 1229            if constexpr (N == 64) {
 
 1230                uint32_t 
const input1 = readLE<32>(input);
 
 1231                uint32_t 
const input2 = readLE<32>(input + len - 4);
 
 1232                uint64_t 
const bitflip = (readLE<64>(secret + 8) ^ readLE<64>(secret + 16)) - seed;
 
 1233                uint64_t 
const input64 = input2 + ((uint64_t) input1 << 32);
 
 1234                uint64_t x = input64 ^ bitflip;
 
 1236                x ^= rotl<64>(x, 49) ^ rotl<64>(x, 24);
 
 1238                x ^= (x >> 35) + len;
 
 1241                return (x ^ (x >> 28));
 
 1243                uint32_t 
const input_lo = readLE<32>(input);
 
 1244                uint32_t 
const input_hi = readLE<32>(input + len - 4);
 
 1245                uint64_t 
const input_64 = input_lo + ((uint64_t) input_hi << 32);
 
 1246                uint64_t 
const bitflip = (readLE<64>(secret + 16) ^ readLE<64>(secret + 24)) + seed;
 
 1247                uint64_t 
const keyed = input_64 ^ bitflip;
 
 1248                uint128_t m128 = mul64to128(keyed, PRIME<64>(1) + (len << 2));
 
 1250                m128.high64 += (m128.low64 << 1);
 
 1251                m128.low64 ^= (m128.high64 >> 3);
 
 1252                m128.low64 ^= (m128.low64 >> 35);
 
 1253                m128.low64 *= mix_constant;
 
 1254                m128.low64 ^= (m128.low64 >> 28);
 
 1255                m128.high64 = avalanche(m128.high64);
 
 1262        XXH_FORCE_INLINE hash_t<N> len_9to16(
const uint8_t *input, 
size_t len, 
const uint8_t *secret, uint64_t seed) {
 
 1263            if constexpr (N == 64) {
 
 1264                uint64_t 
const bitflip1 = (readLE<64>(secret + 24) ^ readLE<64>(secret + 32)) + seed;
 
 1265                uint64_t 
const bitflip2 = (readLE<64>(secret + 40) ^ readLE<64>(secret + 48)) - seed;
 
 1266                uint64_t 
const input_lo = readLE<64>(input) ^ bitflip1;
 
 1267                uint64_t 
const input_hi = readLE<64>(input + len - 8) ^ bitflip2;
 
 1268                uint64_t 
const acc = len + swap<64>(input_lo) + input_hi + mul128fold64(input_lo, input_hi);
 
 1270                return avalanche(acc);
 
 1272                uint64_t 
const bitflipl = (readLE<64>(secret + 32) ^ readLE<64>(secret + 40)) - seed;
 
 1273                uint64_t 
const bitfliph = (readLE<64>(secret + 48) ^ readLE<64>(secret + 56)) + seed;
 
 1274                uint64_t 
const input_lo = readLE<64>(input);
 
 1275                uint64_t input_hi = readLE<64>(input + len - 8);
 
 1276                uint128_t m128 = mul64to128(input_lo ^ input_hi ^ bitflipl, PRIME<64>(1));
 
 1278                m128.low64 += (uint64_t)(len - 1) << 54;
 
 1279                input_hi ^= bitfliph;
 
 1281                if constexpr (
sizeof(
void *) < 
sizeof(uint64_t))
 
 1283                    m128.high64 += (input_hi & 0xFFFFFFFF00000000) + mul32to64((uint32_t) input_hi, PRIME<32>(2));
 
 1285                    m128.high64 += input_hi + mul32to64((uint32_t) input_hi, PRIME<32>(2) - 1);
 
 1288                m128.low64 ^= swap<64>(m128.high64);
 
 1290                hash128_t h128 = mul64to128(m128.low64, PRIME<64>(2));
 
 1292                h128.high64 += m128.high64 * PRIME<64>(2);
 
 1293                h128.low64 = avalanche(h128.low64);
 
 1294                h128.high64 = avalanche(h128.high64);
 
 1301        XXH_FORCE_INLINE hash_t<N> len_0to16(
const uint8_t *input, 
size_t len, 
const uint8_t *secret, uint64_t seed) {
 
 1302            if (XXH_likely(len > 8)) {
 
 1303                return len_9to16<N>(input, len, secret, seed);
 
 1304            } 
else if (XXH_likely(len >= 4)) {
 
 1305                return len_4to8<N>(input, len, secret, seed);
 
 1307                return len_1to3<N>(input, len, secret, seed);
 
 1309                if constexpr (N == 64) {
 
 1310                    return avalanche((PRIME<64>(1) + seed) ^ (readLE<64>(secret + 56) ^ readLE<64>(secret + 64)));
 
 1312                    uint64_t 
const bitflipl = readLE<64>(secret + 64) ^ readLE<64>(secret + 72);
 
 1313                    uint64_t 
const bitfliph = readLE<64>(secret + 80) ^ readLE<64>(secret + 88);
 
 1315                    return hash128_t(avalanche((PRIME<64>(1) + seed) ^ bitflipl), avalanche((PRIME<64>(2) - seed) ^ bitfliph));
 
 1321        XXH_FORCE_INLINE hash_t<N> hash_long_internal(
const uint8_t *XXH_RESTRICT input, 
size_t len, 
const uint8_t *XXH_RESTRICT secret = default_secret, 
size_t secretSize = 
sizeof(default_secret)) {
 
 1322            alignas(acc_align) std::array<uint64_t, acc_nb> acc = init_acc;
 
 1324            if constexpr (N == 64) {
 
 1325                hash_long_internal_loop(acc.data(), input, len, secret, secretSize, acc_width::acc_64bits);
 
 1328                return merge_accs(acc.data(), secret + secret_mergeaccs_start, (uint64_t) len * PRIME<64>(1));
 
 1330                hash_long_internal_loop(acc.data(), input, len, secret, secretSize, acc_width::acc_128bits);
 
 1333                uint64_t 
const low64 = merge_accs(acc.data(), secret + secret_mergeaccs_start, (uint64_t) len * PRIME<64>(1));
 
 1334                uint64_t 
const high64 = merge_accs(acc.data(), secret + secretSize - 
sizeof(acc) - secret_mergeaccs_start, ~((uint64_t) len * PRIME<64>(2)));
 
 1336                return hash128_t(low64, high64);
 
 1340        XXH_FORCE_INLINE uint64_t mix_16b(
const uint8_t *XXH_RESTRICT input, 
const uint8_t *XXH_RESTRICT secret, uint64_t seed) {
 
 1341            uint64_t 
const input_lo = readLE<64>(input);
 
 1342            uint64_t 
const input_hi = readLE<64>(input + 8);
 
 1344            return mul128fold64(input_lo ^ (readLE<64>(secret) + seed), input_hi ^ (readLE<64>(secret + 8) - seed));
 
 1347        XXH_FORCE_INLINE uint128_t mix_32b(uint128_t acc, 
const uint8_t *input1, 
const uint8_t *input2, 
const uint8_t *secret, uint64_t seed) {
 
 1348            acc.low64 += mix_16b(input1, secret + 0, seed);
 
 1349            acc.low64 ^= readLE<64>(input2) + readLE<64>(input2 + 8);
 
 1350            acc.high64 += mix_16b(input2, secret + 16, seed);
 
 1351            acc.high64 ^= readLE<64>(input1) + readLE<64>(input1 + 8);
 
 1357        XXH_FORCE_INLINE hash_t<N> len_17to128(
const uint8_t *XXH_RESTRICT input, 
size_t len, 
const uint8_t *XXH_RESTRICT secret, uint64_t seed) {
 
 1358            if constexpr (N == 64) {
 
 1359                hash64_t acc = len * PRIME<64>(1);
 
 1364                            acc += mix_16b(input + 48, secret + 96, seed);
 
 1365                            acc += mix_16b(input + len - 64, secret + 112, seed);
 
 1368                        acc += mix_16b(input + 32, secret + 64, seed);
 
 1369                        acc += mix_16b(input + len - 48, secret + 80, seed);
 
 1372                    acc += mix_16b(input + 16, secret + 32, seed);
 
 1373                    acc += mix_16b(input + len - 32, secret + 48, seed);
 
 1376                acc += mix_16b(input + 0, secret + 0, seed);
 
 1377                acc += mix_16b(input + len - 16, secret + 16, seed);
 
 1379                return avalanche(acc);
 
 1381                hash128_t acc = {len * PRIME<64>(1), 0};
 
 1386                            acc = mix_32b(acc, input + 48, input + len - 64, secret + 96, seed);
 
 1389                        acc = mix_32b(acc, input + 32, input + len - 48, secret + 64, seed);
 
 1392                    acc = mix_32b(acc, input + 16, input + len - 32, secret + 32, seed);
 
 1395                acc = mix_32b(acc, input, input + len - 16, secret, seed);
 
 1397                uint64_t 
const low64 = acc.low64 + acc.high64;
 
 1398                uint64_t 
const high64 = (acc.low64 * PRIME<64>(1)) + (acc.high64 * PRIME<64>(4)) + ((len - seed) * PRIME<64>(2));
 
 1400                return {avalanche(low64), (uint64_t) 0 - avalanche(high64)};
 
 1405        XXH_NO_INLINE hash_t<N> len_129to240(
const uint8_t *XXH_RESTRICT input, 
size_t len, 
const uint8_t *XXH_RESTRICT secret, uint64_t seed) {
 
 1406            if constexpr (N == 64) {
 
 1407                uint64_t acc = len * PRIME<64>(1);
 
 1408                size_t const nbRounds = len / 16;
 
 1410                for (
size_t i = 0; i < 8; i++) {
 
 1411                    acc += mix_16b(input + (i * 16), secret + (i * 16), seed);
 
 1414                acc = avalanche(acc);
 
 1416                for (
size_t i = 8; i < nbRounds; i++) {
 
 1417                    acc += mix_16b(input + (i * 16), secret + ((i - 8) * 16) + midsize_startoffset, seed);
 
 1421                acc += mix_16b(input + len - 16, secret + secret_size_min - midsize_lastoffset, seed);
 
 1423                return avalanche(acc);
 
 1426                uint64_t 
const nbRounds = len / 32;
 
 1428                acc.low64 = len * PRIME<64>(1);
 
 1431                for (
size_t i = 0; i < 4; i++) {
 
 1432                    acc = mix_32b(acc, input + (i * 32), input + (i * 32) + 16, secret + (i * 32), seed);
 
 1435                acc.low64 = avalanche(acc.low64);
 
 1436                acc.high64 = avalanche(acc.high64);
 
 1438                for (
size_t i = 4; i < nbRounds; i++) {
 
 1439                    acc = mix_32b(acc, input + (i * 32), input + (i * 32) + 16, secret + midsize_startoffset + ((i - 4) * 32), seed);
 
 1443                acc = mix_32b(acc, input + len - 16, input + len - 32, secret + secret_size_min - midsize_lastoffset - 16, 0ULL - seed);
 
 1445                uint64_t 
const low64 = acc.low64 + acc.high64;
 
 1446                uint64_t 
const high64 = (acc.low64 * PRIME<64>(1)) + (acc.high64 * PRIME<64>(4)) + ((len - seed) * PRIME<64>(2));
 
 1448                return {avalanche(low64), (uint64_t) 0 - avalanche(high64)};
 
 1453        XXH_NO_INLINE hash_t<N> xxhash3_impl(
const void *XXH_RESTRICT input, 
size_t len, hash64_t seed, 
const void *XXH_RESTRICT secret = default_secret, 
size_t secretSize = secret_default_size) {
 
 1454            alignas(8) uint8_t custom_secret[secret_default_size];
 
 1455            const void *short_secret = secret;
 
 1458                init_custom_secret(custom_secret, seed);
 
 1459                secret = custom_secret;
 
 1460                secretSize = secret_default_size;
 
 1461                short_secret = default_secret;
 
 1465                return len_0to16<N>(
static_cast<const uint8_t *
>(input), len, 
static_cast<const uint8_t *
>(short_secret), seed);
 
 1466            } 
else if (len <= 128) {
 
 1467                return len_17to128<N>(
static_cast<const uint8_t *
>(input), len, 
static_cast<const uint8_t *
>(short_secret), seed);
 
 1468            } 
else if (len <= midsize_max) {
 
 1469                return len_129to240<N>(
static_cast<const uint8_t *
>(input), len, 
static_cast<const uint8_t *
>(short_secret), seed);
 
 1471                return hash_long_internal<N>(
static_cast<const uint8_t *
>(input), len, 
static_cast<const uint8_t *
>(secret), secretSize);
 
 1481    template<
size_t bit_mode>
 
 1482    inline hash_t<bit_mode> xxhash(
const void *input, 
size_t len, uint_t<bit_mode> seed = 0) {
 
 1483        static_assert(!(bit_mode != 32 && bit_mode != 64), 
"xxhash can only be used in 32 and 64 bit modes.");
 
 1484        return detail::endian_align<bit_mode>(input, len, seed);
 
 1487    template<
size_t bit_mode, 
typename T>
 
 1488    inline hash_t<bit_mode> xxhash(
const std::basic_string<T> &input, uint_t<bit_mode> seed = 0) {
 
 1489        static_assert(!(bit_mode != 32 && bit_mode != 64), 
"xxhash can only be used in 32 and 64 bit modes.");
 
 1490        return detail::endian_align<bit_mode>(
static_cast<const void *
>(input.data()), input.length() * 
sizeof(T), seed);
 
 1493    template<
size_t bit_mode, 
typename ContiguousIterator>
 
 1494    inline hash_t<bit_mode> xxhash(ContiguousIterator begin, ContiguousIterator end, uint_t<bit_mode> seed = 0) {
 
 1495        static_assert(!(bit_mode != 32 && bit_mode != 64), 
"xxhash can only be used in 32 and 64 bit modes.");
 
 1496        using T = 
typename std::decay_t<
decltype(*end)>;
 
 1497        return detail::endian_align<bit_mode>(
static_cast<const void *
>(&*begin), (end - begin) * 
sizeof(T), seed);
 
 1500    template<
size_t bit_mode, 
typename T>
 
 1501    inline hash_t<bit_mode> xxhash(
const std::vector<T> &input, uint_t<bit_mode> seed = 0) {
 
 1502        static_assert(!(bit_mode != 32 && bit_mode != 64), 
"xxhash can only be used in 32 and 64 bit modes.");
 
 1503        return detail::endian_align<bit_mode>(
static_cast<const void *
>(input.data()), input.size() * 
sizeof(T), seed);
 
 1506    template<
size_t bit_mode, 
typename T, 
size_t AN>
 
 1507    inline hash_t<bit_mode> xxhash(
const std::array<T, AN> &input, uint_t<bit_mode> seed = 0) {
 
 1508        static_assert(!(bit_mode != 32 && bit_mode != 64), 
"xxhash can only be used in 32 and 64 bit modes.");
 
 1509        return detail::endian_align<bit_mode>(
static_cast<const void *
>(input.data()), AN * 
sizeof(T), seed);
 
 1512    template<
size_t bit_mode, 
typename T>
 
 1513    inline hash_t<bit_mode> xxhash(
const std::initializer_list<T> &input, uint_t<bit_mode> seed = 0) {
 
 1514        static_assert(!(bit_mode != 32 && bit_mode != 64), 
"xxhash can only be used in 32 and 64 bit modes.");
 
 1515        return detail::endian_align<bit_mode>(
static_cast<const void *
>(input.begin()), input.size() * 
sizeof(T), seed);
 
 1523    template<
size_t bit_mode>
 
 1524    inline hash_t<bit_mode> xxhash3(
const void *input, 
size_t len, uint64_t seed = 0) {
 
 1525        static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 can only be used in 64 and 128 bit modes.");
 
 1526        return detail3::xxhash3_impl<bit_mode>(input, len, seed);
 
 1529    template<
size_t bit_mode>
 
 1530    inline hash_t<bit_mode> xxhash3(
const void *input, 
size_t len, 
const void *secret, 
size_t secretSize) {
 
 1531        static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 can only be used in 64 and 128 bit modes.");
 
 1532        return detail3::xxhash3_impl<bit_mode>(input, len, 0, secret, secretSize);
 
 1535    template<
size_t bit_mode, 
typename T>
 
 1536    inline hash_t<bit_mode> xxhash3(
const std::basic_string<T> &input, uint64_t seed = 0) {
 
 1537        static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 can only be used in 64 and 128 bit modes.");
 
 1538        return detail3::xxhash3_impl<bit_mode>(
static_cast<const void *
>(input.data()), input.length() * 
sizeof(T), seed);
 
 1541    template<
size_t bit_mode, 
typename T>
 
 1542    inline hash_t<bit_mode> xxhash3(
const std::basic_string<T> &input, 
const void *secret, 
size_t secretSize) {
 
 1543        static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 can only be used in 64 and 128 bit modes.");
 
 1544        return detail3::xxhash3_impl<bit_mode>(
static_cast<const void *
>(input.data()), input.length() * 
sizeof(T), 0, secret, secretSize);
 
 1547    template<
size_t N, 
typename ContiguousIterator>
 
 1548    inline hash_t<N> xxhash3(ContiguousIterator begin, ContiguousIterator end, uint64_t seed = 0) {
 
 1549        static_assert(!(N != 128 && N != 64), 
"xxhash3 can only be used in 64 and 128 bit modes.");
 
 1550        using T = 
typename std::decay_t<
decltype(*end)>;
 
 1551        return detail3::xxhash3_impl<N>(
static_cast<const void *
>(&*begin), (end - begin) * 
sizeof(T), seed);
 
 1554    template<
size_t bit_mode, 
typename ContiguousIterator>
 
 1555    inline hash_t<bit_mode> xxhash3(ContiguousIterator begin, ContiguousIterator end, 
const void *secret, 
size_t secretSize) {
 
 1556        static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 can only be used in 64 and 128 bit modes.");
 
 1557        using T = 
typename std::decay_t<
decltype(*end)>;
 
 1558        return detail3::xxhash3_impl<bit_mode>(
static_cast<const void *
>(&*begin), (end - begin) * 
sizeof(T), 0, secret, secretSize);
 
 1561    template<
size_t bit_mode, 
typename T>
 
 1562    inline hash_t<bit_mode> xxhash3(
const std::vector<T> &input, uint64_t seed = 0) {
 
 1563        static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 can only be used in 64 and 128 bit modes.");
 
 1564        return detail3::xxhash3_impl<bit_mode>(
static_cast<const void *
>(input.data()), input.size() * 
sizeof(T), seed);
 
 1567    template<
size_t bit_mode, 
typename T>
 
 1568    inline hash_t<bit_mode> xxhash3(
const std::vector<T> &input, 
const void *secret, 
size_t secretSize) {
 
 1569        static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 can only be used in 64 and 128 bit modes.");
 
 1570        return detail3::xxhash3_impl<bit_mode>(
static_cast<const void *
>(input.data()), input.size() * 
sizeof(T), 0, secret, secretSize);
 
 1573    template<
size_t bit_mode, 
typename T, 
size_t AN>
 
 1574    inline hash_t<bit_mode> xxhash3(
const std::array<T, AN> &input, uint64_t seed = 0) {
 
 1575        static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 can only be used in 64 and 128 bit modes.");
 
 1576        return detail3::xxhash3_impl<bit_mode>(
static_cast<const void *
>(input.data()), AN * 
sizeof(T), seed);
 
 1579    template<
size_t bit_mode, 
typename T, 
size_t AN>
 
 1580    inline hash_t<bit_mode> xxhash3(
const std::array<T, AN> &input, 
const void *secret, 
size_t secretSize) {
 
 1581        static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 can only be used in 64 and 128 bit modes.");
 
 1582        return detail3::xxhash3_impl<bit_mode>(
static_cast<const void *
>(input.data()), AN * 
sizeof(T), 0, secret, secretSize);
 
 1585    template<
size_t bit_mode, 
typename T>
 
 1586    inline hash_t<bit_mode> xxhash3(
const std::initializer_list<T> &input, uint64_t seed = 0) {
 
 1587        static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 can only be used in 64 and 128 bit modes.");
 
 1588        return detail3::xxhash3_impl<bit_mode>(
static_cast<const void *
>(input.begin()), input.size() * 
sizeof(T), seed);
 
 1591    template<
size_t bit_mode, 
typename T>
 
 1592    inline hash_t<bit_mode> xxhash3(
const std::initializer_list<T> &input, 
const void *secret, 
size_t secretSize) {
 
 1593        static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 can only be used in 64 and 128 bit modes.");
 
 1594        return detail3::xxhash3_impl<bit_mode>(
static_cast<const void *
>(input.begin()), input.size() * 
sizeof(T), 0, secret, secretSize);
 
 1602    template<
size_t bit_mode>
 
 1604        uint64_t total_len = 0;
 
 1605        uint_t<bit_mode> v1 = 0, v2 = 0, v3 = 0, v4 = 0;
 
 1606        std::array<hash_t<bit_mode>, 4> mem = {0, 0, 0, 0};
 
 1607        uint32_t memsize = 0;
 
 1609        inline void update_impl(
const void *input, 
size_t length) {
 
 1610            const uint8_t *p = 
reinterpret_cast<const uint8_t *
>(input);
 
 1611            const uint8_t *
const bEnd = p + length;
 
 1613            total_len += length;
 
 1615            if (memsize + length < (bit_mode / 2)) { 
 
 1616                memcpy(
reinterpret_cast<uint8_t *
>(mem.data()) + memsize, input, length);
 
 1617                memsize += 
static_cast<uint32_t
>(length);
 
 1622                memcpy(
reinterpret_cast<uint8_t *
>(mem.data()) + memsize, input, (bit_mode / 2) - memsize);
 
 1624                const uint_t<bit_mode> *ptr = mem.data();
 
 1626                v1 = detail::round<bit_mode>(v1, mem_ops::readLE<bit_mode>(ptr));
 
 1628                v2 = detail::round<bit_mode>(v2, mem_ops::readLE<bit_mode>(ptr));
 
 1630                v3 = detail::round<bit_mode>(v3, mem_ops::readLE<bit_mode>(ptr));
 
 1632                v4 = detail::round<bit_mode>(v4, mem_ops::readLE<bit_mode>(ptr));
 
 1634                p += (bit_mode / 2) - memsize;
 
 1638            if (p <= bEnd - (bit_mode / 2)) {
 
 1639                const uint8_t *
const limit = bEnd - (bit_mode / 2);
 
 1642                    v1 = detail::round<bit_mode>(v1, mem_ops::readLE<bit_mode>(p));
 
 1643                    p += (bit_mode / 8);
 
 1644                    v2 = detail::round<bit_mode>(v2, mem_ops::readLE<bit_mode>(p));
 
 1645                    p += (bit_mode / 8);
 
 1646                    v3 = detail::round<bit_mode>(v3, mem_ops::readLE<bit_mode>(p));
 
 1647                    p += (bit_mode / 8);
 
 1648                    v4 = detail::round<bit_mode>(v4, mem_ops::readLE<bit_mode>(p));
 
 1649                    p += (bit_mode / 8);
 
 1650                } 
while (p <= limit);
 
 1654                memcpy(mem.data(), p, 
static_cast<size_t>(bEnd - p));
 
 1655                memsize = 
static_cast<uint32_t
>(bEnd - p);
 
 1659        inline hash_t<bit_mode> digest_impl()
 const {
 
 1660            const uint8_t *p = 
reinterpret_cast<const uint8_t *
>(mem.data());
 
 1661            const uint8_t *
const bEnd = 
reinterpret_cast<const uint8_t *
>(mem.data()) + memsize;
 
 1662            hash_t<bit_mode> hash_ret;
 
 1664            if (total_len >= (bit_mode / 2)) {
 
 1665                hash_ret = bit_ops::rotl<bit_mode>(v1, 1) + bit_ops::rotl<bit_mode>(v2, 7) + bit_ops::rotl<bit_mode>(v3, 12) + bit_ops::rotl<bit_mode>(v4, 18);
 
 1667                if constexpr (bit_mode == 64) {
 
 1668                    detail::endian_align_sub_mergeround(hash_ret, v1, v2, v3, v4);
 
 1671                hash_ret = v3 + detail::PRIME<bit_mode>(5);
 
 1674            hash_ret += 
static_cast<hash_t<bit_mode>
>(total_len);
 
 1676            return detail::endian_align_sub_ending<bit_mode>(hash_ret, p, bEnd);
 
 1681            static_assert(!(bit_mode != 32 && bit_mode != 64), 
"xxhash streaming can only be used in 32 and 64 bit modes.");
 
 1682            v1 = seed + detail::PRIME<bit_mode>(1) + detail::PRIME<bit_mode>(2);
 
 1683            v2 = seed + detail::PRIME<bit_mode>(2);
 
 1685            v4 = seed - detail::PRIME<bit_mode>(1);
 
 1692        void reset(uint_t<bit_mode> seed = 0) {
 
 1694            v1 = seed + detail::PRIME<bit_mode>(1) + detail::PRIME<bit_mode>(2);
 
 1695            v2 = seed + detail::PRIME<bit_mode>(2);
 
 1697            v4 = seed - detail::PRIME<bit_mode>(1);
 
 1700        void update(
const void *input, 
size_t length) {
 
 1701            return update_impl(input, length);
 
 1704        template<
typename T>
 
 1705        void update(
const std::basic_string<T> &input) {
 
 1706            return update_impl(
static_cast<const void *
>(input.data()), input.length() * 
sizeof(T));
 
 1709        template<
typename ContiguousIterator>
 
 1710        void update(ContiguousIterator begin, ContiguousIterator end) {
 
 1711            using T = 
typename std::decay_t<
decltype(*end)>;
 
 1712            return update_impl(
static_cast<const void *
>(&*begin), (end - begin) * 
sizeof(T));
 
 1715        template<
typename T>
 
 1716        void update(
const std::vector<T> &input) {
 
 1717            return update_impl(
static_cast<const void *
>(input.data()), input.size() * 
sizeof(T));
 
 1720        template<
typename T, 
size_t AN>
 
 1721        void update(
const std::array<T, AN> &input) {
 
 1722            return update_impl(
static_cast<const void *
>(input.data()), AN * 
sizeof(T));
 
 1725        template<
typename T>
 
 1726        void update(
const std::initializer_list<T> &input) {
 
 1727            return update_impl(
static_cast<const void *
>(input.begin()), input.size() * 
sizeof(T));
 
 1730        hash_t<bit_mode> digest()
 const {
 
 1731            return digest_impl();
 
 
 1743    template<
size_t bit_mode>
 
 1745        constexpr static int internal_buffer_size = 256;
 
 1746        constexpr static int internal_buffer_stripes = (internal_buffer_size / detail3::stripe_len);
 
 1747        constexpr static detail3::acc_width accWidth = (bit_mode == 64) ? detail3::acc_width::acc_64bits : detail3::acc_width::acc_128bits;
 
 1749        alignas(64) uint64_t acc[8];
 
 1750        alignas(64) uint8_t customSecret[detail3::secret_default_size]; 
 
 1751        alignas(64) uint8_t buffer[internal_buffer_size];
 
 1752        uint32_t bufferedSize = 0;
 
 1753        uint32_t nbStripesPerBlock = 0;
 
 1754        uint32_t nbStripesSoFar = 0;
 
 1755        uint32_t secretLimit = 0;
 
 1756        uint32_t reserved32 = 0;
 
 1757        uint32_t reserved32_2 = 0;
 
 1758        uint64_t totalLen = 0;
 
 1760        uint64_t reserved64 = 0;
 
 1761        const uint8_t *secret = 
nullptr; 
 
 1764        void consume_stripes(uint64_t *acc, uint32_t &nbStripesSoFar, 
size_t totalStripes, 
const uint8_t *input, detail3::acc_width accWidth) {
 
 1765            if (nbStripesPerBlock - nbStripesSoFar <= totalStripes) 
 
 1767                size_t const nbStripes = nbStripesPerBlock - nbStripesSoFar;
 
 1769                detail3::accumulate(acc, input, secret + (nbStripesSoFar * detail3::secret_consume_rate), nbStripes, accWidth);
 
 1770                detail3::scramble_acc<detail3::vector_mode>(acc, secret + secretLimit);
 
 1771                detail3::accumulate(acc, input + nbStripes * detail3::stripe_len, secret, totalStripes - nbStripes, accWidth);
 
 1772                nbStripesSoFar = (uint32_t)(totalStripes - nbStripes);
 
 1774                detail3::accumulate(acc, input, secret + (nbStripesSoFar * detail3::secret_consume_rate), totalStripes, accWidth);
 
 1775                nbStripesSoFar += (uint32_t) totalStripes;
 
 1779        void update_impl(
const void *input_, 
size_t len) {
 
 1780            const uint8_t *input = 
static_cast<const uint8_t *
>(input_);
 
 1781            const uint8_t *
const bEnd = input + len;
 
 1785            if (bufferedSize + len <= internal_buffer_size) { 
 
 1786                memcpy(buffer + bufferedSize, input, len);
 
 1787                bufferedSize += (uint32_t) len;
 
 1792            if (bufferedSize > 0) { 
 
 1793                size_t const loadSize = internal_buffer_size - bufferedSize;
 
 1795                memcpy(buffer + bufferedSize, input, loadSize);
 
 1797                consume_stripes(acc, nbStripesSoFar, internal_buffer_stripes, buffer, accWidth);
 
 1802            if (input + internal_buffer_size <= bEnd) {
 
 1803                const uint8_t *
const limit = bEnd - internal_buffer_size;
 
 1806                    consume_stripes(acc, nbStripesSoFar, internal_buffer_stripes, input, accWidth);
 
 1807                    input += internal_buffer_size;
 
 1808                } 
while (input <= limit);
 
 1812                memcpy(buffer, input, (
size_t)(bEnd - input));
 
 1813                bufferedSize = (uint32_t)(bEnd - input);
 
 1817        void digest_long(uint64_t *acc_, detail3::acc_width accWidth) {
 
 1818            memcpy(acc_, acc, 
sizeof(acc)); 
 
 1820            if (bufferedSize >= detail3::stripe_len) {
 
 1821                size_t const totalNbStripes = bufferedSize / detail3::stripe_len;
 
 1822                uint32_t nbStripesSoFar = this->nbStripesSoFar;
 
 1824                consume_stripes(acc_, nbStripesSoFar, totalNbStripes, buffer, accWidth);
 
 1826                if (bufferedSize % detail3::stripe_len) { 
 
 1827                    detail3::accumulate_512<detail3::vector_mode>(acc_, buffer + bufferedSize - detail3::stripe_len, secret + secretLimit - detail3::secret_lastacc_start, accWidth);
 
 1830                if (bufferedSize > 0) { 
 
 1831                    uint8_t lastStripe[detail3::stripe_len];
 
 1832                    size_t const catchupSize = detail3::stripe_len - bufferedSize;
 
 1833                    memcpy(lastStripe, buffer + 
sizeof(buffer) - catchupSize, catchupSize);
 
 1834                    memcpy(lastStripe + catchupSize, buffer, bufferedSize);
 
 1835                    detail3::accumulate_512<detail3::vector_mode>(acc_, lastStripe, secret + secretLimit - detail3::secret_lastacc_start, accWidth);
 
 1846            static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 streaming can only be used in 64 and 128 bit modes.");
 
 1851            static_assert(!(bit_mode != 128 && bit_mode != 64), 
"xxhash3 streaming can only be used in 64 and 128 bit modes.");
 
 1852            reset(secret, secretSize);
 
 1855        void reset(uint64_t seed = 0) {
 
 1856            memset(
this, 0, 
sizeof(*
this));
 
 1857            memcpy(acc, detail3::init_acc.data(), 
sizeof(detail3::init_acc));
 
 1858            (*this).seed = seed;
 
 1861                secret = detail3::default_secret;
 
 1863                detail3::init_custom_secret(customSecret, seed);
 
 1864                secret = customSecret;
 
 1867            secretLimit = (uint32_t)(detail3::secret_default_size - detail3::stripe_len);
 
 1868            nbStripesPerBlock = secretLimit / detail3::secret_consume_rate;
 
 1871        void reset(
const void *secret, 
size_t secretSize) {
 
 1872            memset(
this, 0, 
sizeof(*
this));
 
 1873            memcpy(acc, detail3::init_acc.data(), 
sizeof(detail3::init_acc));
 
 1876            (*this).secret = (
const uint8_t *) secret;
 
 1877            secretLimit = (uint32_t)(secretSize - detail3::stripe_len);
 
 1878            nbStripesPerBlock = secretLimit / detail3::secret_consume_rate;
 
 1881        void update(
const void *input, 
size_t len) {
 
 1882            return update_impl(
static_cast<const void *
>(input), len);
 
 1885        template<
typename T>
 
 1886        void update(
const std::basic_string<T> &input) {
 
 1887            return update_impl(
static_cast<const void *
>(input.data()), input.length() * 
sizeof(T));
 
 1890        template<
typename ContiguousIterator>
 
 1891        void update(ContiguousIterator begin, ContiguousIterator end) {
 
 1892            using T = 
typename std::decay_t<
decltype(*end)>;
 
 1893            return update_impl(
static_cast<const void *
>(&*begin), (end - begin) * 
sizeof(T));
 
 1896        template<
typename T>
 
 1897        void update(
const std::vector<T> &input) {
 
 1898            return update_impl(
static_cast<const void *
>(input.data()), input.size() * 
sizeof(T));
 
 1901        template<
typename T, 
size_t AN>
 
 1902        void update(
const std::array<T, AN> &input) {
 
 1903            return update_impl(
static_cast<const void *
>(input.data()), AN * 
sizeof(T));
 
 1906        template<
typename T>
 
 1907        void update(
const std::initializer_list<T> &input) {
 
 1908            return update_impl(
static_cast<const void *
>(input.begin()), input.size() * 
sizeof(T));
 
 1911        hash_t<bit_mode> digest() {
 
 1912            if (totalLen > detail3::midsize_max) {
 
 1913                alignas(detail3::acc_align) hash64_t acc[detail3::acc_nb];
 
 1915                digest_long(acc, accWidth);
 
 1917                if constexpr (bit_mode == 64) {
 
 1918                    return detail3::merge_accs(acc, secret + detail3::secret_mergeaccs_start, (uint64_t) totalLen * detail::PRIME<64>(1));
 
 1920                    uint64_t 
const low64 = detail3::merge_accs(acc, secret + detail3::secret_mergeaccs_start, (uint64_t) totalLen * detail::PRIME<64>(1));
 
 1921                    uint64_t 
const high64 = detail3::merge_accs(acc, secret + secretLimit + detail3::stripe_len - 
sizeof(acc) - detail3::secret_mergeaccs_start, ~((uint64_t) totalLen * detail::PRIME<64>(2)));
 
 1923                    return {low64, high64};
 
 1926                return detail3::xxhash3_impl<bit_mode>(buffer, totalLen, seed, secret, secretLimit + detail3::stripe_len);
 
 
 1939    template<
size_t bit_mode>
 
 1941        std::array<uint8_t, bit_mode / 8> digest{0};
 
 1944            if constexpr (bit_mode < 128) {
 
 1945                if (mem_ops::is_little_endian()) {
 
 1946                    hash = bit_ops::swap<bit_mode>(hash);
 
 1951                if (mem_ops::is_little_endian()) {
 
 1952                    hash.low64 = bit_ops::swap<64>(hash.low64);
 
 1953                    hash.high64 = bit_ops::swap<64>(hash.high64);
 
 1956                memcpy(digest.data(), &hash.high64, 
sizeof(hash.high64));
 
 1957                memcpy(digest.data() + 
sizeof(hash.high64), &hash.low64, 
sizeof(hash.low64));
 
 1961        hash_t<bit_mode> get_hash()
 const {
 
 1962            if constexpr (bit_mode < 128) {
 
 1963                return mem_ops::readBE<bit_mode>(&digest);
 
 1965                return {mem_ops::readBE<64>(&digest[8]), mem_ops::readBE<64>(&digest)};
 
 
Definition xxhash.hpp:1744
 
Definition xxhash.hpp:1603
 
Definition xxhash.hpp:1940
 
Definition xxhash.hpp:304
 
Definition xxhash.hpp:352
 
Definition xxhash.hpp:325