/* * 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_ */