34 inline size_t hash_combine(
size_t seed,
size_t value) {
35 return seed ^ (value + 0x9e3779b9 + (seed << 6u) + (seed >> 2u));
42 namespace _hash_detail {
46 size_t simple_get_hash(
const T& o);
48 template<
typename T,
typename V>
49 using type_if_not_enum =
typename std::enable_if<!std::is_enum<T>::value, V>::type;
57 auto dispatch_hash(
const T& o) -> decltype(std::hash<T>()(o), type_if_not_enum<T, size_t>()) {
58 return std::hash<T>()(o);
62 typename std::enable_if<std::is_enum<T>::value,
size_t>::type dispatch_hash(
const T& o) {
63 using R =
typename std::underlying_type<T>::type;
64 return std::hash<R>()(static_cast<R>(o));
68 auto dispatch_hash(
const T& o) -> decltype(T::hash(o),
size_t()) {
77 size_t operator()(
const T& o)
const {
78 return _hash_detail::dispatch_hash(o);
83 template<
typename... Types>
85 template<
size_t idx,
typename... Ts>
87 size_t operator()(
const std::tuple<Ts...>& t)
const {
88 return hash_combine(_hash_detail::simple_get_hash(std::get<idx>(t)),
89 tuple_hash<idx-1, Ts...>()(t));
93 template<
typename... Ts>
94 struct tuple_hash<0, Ts...> {
95 size_t operator()(
const std::tuple<Ts...>& t)
const {
96 return _hash_detail::simple_get_hash(std::get<0>(t));
100 size_t operator()(
const std::tuple<Types...>& t)
const {
101 return tuple_hash<
sizeof...(Types)-1, Types...>()(t);
108 size_t operator()(
const std::vector<T>& v)
const {
110 for (
const auto & elem : v) {
111 seed = hash_combine(seed, _hash_detail::simple_get_hash(elem));
117 namespace _hash_detail {
120 size_t simple_get_hash(
const T& o) {
133 template<
typename... Types>
134 size_t get_hash(
const Types&... args) {
135 return torch::hash<decltype(std::tie(args...))>()(std::tie(args...));