#pragma once #include "util/types.hpp" #include namespace rpcs3 { constexpr usz fnv_seed = 14695981039346656037ull; constexpr usz fnv_prime = 1099511628211ull; template static usz hash_base(T value) { return static_cast(value); } template ::value>> static inline usz hash64(usz hash_value, T data) { hash_value ^= data; hash_value *= fnv_prime; return hash_value; } template static usz hash_struct_base(const T& value) { // FNV 64-bit usz result = fnv_seed; const uchar* bits = reinterpret_cast(&value); for (usz n = 0; n < (sizeof(T) / sizeof(U)); ++n) { U val{}; std::memcpy(&val, bits + (n * sizeof(U)), sizeof(U)); result = hash64(result, val); } return result; } template static usz hash_struct(const T& value) { static constexpr auto block_sz = sizeof(T); if constexpr ((block_sz & 0x7) == 0) { return hash_struct_base(value); } if constexpr ((block_sz & 0x3) == 0) { return hash_struct_base(value); } if constexpr ((block_sz & 0x1) == 0) { return hash_struct_base(value); } return hash_struct_base(value); } }