#pragma once #include #include "../concepts/snplib_concepts.h" namespace snplib { template static constexpr size_t hash_FNV1a(const R& r) { static_assert(sizeof(size_t) == 8 || sizeof(size_t) == 4, "The ONLY 32 or 64-bit std::size_t are supported!!!"); size_t hash = 0, prime = 0; if constexpr (sizeof(size_t) == 8) { // 64-bit prime = 1099511628211UL; hash = 14695981039346656037UL; } else if constexpr (sizeof(size_t) == 4) { // 32-bit prime = 16777619; hash = 2166136261; } for (const char& ch : r) { hash ^= ch; hash *= prime; } return hash; } static constexpr size_t hash_FNV1a(std::forward_iterator auto begin, std::sentinel_for auto end) requires std::same_as>, char> { static_assert(sizeof(size_t) == 8 || sizeof(size_t) == 4, "The ONLY 32 or 64-bit std::size_t are supported!!!"); size_t hash = 0, prime = 0; if constexpr (sizeof(size_t) == 8) { // 64-bit prime = 1099511628211UL; hash = 14695981039346656037UL; } else if constexpr (sizeof(size_t) == 4) { // 32-bit prime = 16777619; hash = 2166136261; } for (auto it = begin; it != end; ++it) { hash ^= *it; hash *= prime; } return hash; } // Boost implementation of hash combining template static constexpr void snplib_hash_combine(std::size_t& seed, const T& v, Ts&&... vs) { static constexpr auto digits = std::numeric_limits::digits; static_assert(digits == 64 || digits == 32, "The ONLY 32 or 64-bit std::size_t are supported!!!"); if constexpr (digits == 64) { std::size_t x = seed + 0x9e3779b9 + std::hash()(v); const std::size_t m = 0xe9846af9b1a615d; x ^= x >> 32; x *= m; x ^= x >> 32; x *= m; x ^= x >> 28; seed = x; } else { // 32-bits std::size_t x = seed + 0x9e3779b9 + std::hash()(v); const std::size_t m1 = 0x21f0aaad; const std::size_t m2 = 0x735a2d97; x ^= x >> 16; x *= m1; x ^= x >> 15; x *= m2; x ^= x >> 15; seed = x; } if constexpr (sizeof...(Ts)) { snplib_hash_combine(seed, std::forward(vs)...); } } } // namespace snplib