#pragma once #include #include #include "types.h" // only works for 64 bit systems constexpr size_t _FNV_offset_basis = 14695981039346656037ULL; constexpr size_t _FNV_prime = 1099511628211ULL; inline size_t append_bytes(const unsigned char* _First) noexcept { size_t _Val = _FNV_offset_basis; for (; *_First; ++_First) { _Val ^= static_cast(*_First); _Val *= _FNV_prime; } return _Val; } namespace std{ template<> struct hash { size_t operator()(const astring_view& _Keyval) const noexcept { return append_bytes(_Keyval.str); } }; template<> struct hash { size_t operator() (const types::date_t& _Keyval) const noexcept { return std::hash()(*(unsigned int*)(&_Keyval)); } }; template<> struct hash { size_t operator() (const types::time_t& _Keyval) const noexcept { return std::hash()(_Keyval.ms) ^ std::hash()(_Keyval.seconds) ^ std::hash()(_Keyval.minutes) ^ std::hash()(_Keyval.hours) ; } }; template<> struct hash{ size_t operator() (const types::timestamp_t& _Keyval) const noexcept { return std::hash()(_Keyval.date) ^ std::hash()(_Keyval.time); } }; } inline size_t append_bytes(const astring_view& view) noexcept { return append_bytes(view.str); } template struct hasher { template typename std::enable_if< i == sizeof...(Types), size_t>::type hashi(const std::tuple& record) const { return 534235245539ULL; } template typename std::enable_if< i < sizeof ...(Types), size_t>::type hashi(const std::tuple& record) const { using current_type = typename std::decay>::type>::type; return std::hash()(std::get(record)) ^ hashi(record); } size_t operator()(const std::tuple& record) const { return hashi(record); } };