/*
* Copyright (C) 2015 ScyllaDB
*/
/*
* This file is part of Scylla.
*
* Scylla is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Scylla is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Scylla. If not, see .
*/
#ifndef UTILS_HASH_HH_
#define UTILS_HASH_HH_
#include
#include "core/apply.hh"
namespace utils {
// public for unit testing etc
inline size_t hash_combine(size_t left, size_t right) {
return left + 0x9e3779b9 + (right << 6) + (right >> 2);
}
struct tuple_hash {
private:
// CMH. Add specializations here to handle recursive tuples
template
static size_t hash(const T& t) {
return std::hash()(t);
}
template
struct hash_impl {
size_t operator()(const std::tuple& t, size_t a) const {
return hash_impl()(t, hash_combine(hash(std::get(t)), a));
}
size_t operator()(const std::tuple& t) const {
return hash_impl()(t, hash(std::get(t)));
}
};
template
struct hash_impl<0, Types...> {
size_t operator()(const std::tuple& t, size_t a) const {
return hash_combine(hash(std::get<0>(t)), a);
}
size_t operator()(const std::tuple& t) const {
return hash(std::get<0>(t));
}
};
public:
template
size_t operator()(const std::pair& p) const {
return hash_combine(hash(p.first), hash(p.second));
}
template
size_t operator()(const T1& t1, const T2& t2) const {
return hash_combine(hash(t1), hash(t2));
}
template
size_t operator()(const std::tuple& v) const;
};
template
inline size_t tuple_hash::operator()(const std::tuple& v) const {
return hash_impl>::value - 1, Args...>()(v);
}
template<>
inline size_t tuple_hash::operator()(const std::tuple<>& v) const {
return 0;
}
}
#endif /* UTILS_HASH_HH_ */