Program Listing for File hash.h
↰ Return to documentation for file (liberate/cpp/hash.h
)
/*
* This file is part of liberate.
*
* Author(s): Jens Finkhaeuser <jens@finkhaeuser.de>
*
* Copyright (c) 2014-2015 Unwesen Ltd.
* Copyright (c) 2016-2021 Jens Finkhaeuser.
* Copyright (c) 2022 Interpeer gUG (haftungsbeschränkt)
*
* SPDX-License-Identifier: GPL-3.0-only
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIBERATE_CPP_HASH_H
#define LIBERATE_CPP_HASH_H
#ifndef __cplusplus
#error You are trying to include a C++ only header file
#endif
#include <liberate.h>
#include <functional>
#include <cstddef>
#define LIBERATE_MAKE_HASHABLE(type) \
namespace std { \
template <> struct hash<type> { \
std::size_t operator()(type const & t) const noexcept { \
return t.hash(); \
} \
}; \
}
namespace liberate::cpp {
inline void
hash_combine(std::size_t & seed, std::size_t const & value)
{
seed ^= value + 0x9e3779b9
+ (seed << 6) + (seed >> 2);
}
template <typename T>
inline std::size_t
multi_hash(T const & t)
{
return std::hash<T>()(t);
}
template <typename T0, typename... Ts>
inline std::size_t
multi_hash(T0 const & t0, Ts && ... ts)
{
std::size_t seed = multi_hash(t0);
if constexpr (0 == sizeof...(ts)) {
return seed;
}
std::size_t remainder = multi_hash(std::forward<Ts>(ts)...);
hash_combine(seed, remainder);
return seed;
}
template <typename iterT>
inline std::size_t
range_hash(iterT const & begin, iterT const & end)
{
iterT cur = begin;
std::size_t hash = 0;
std::hash<typename std::iterator_traits<iterT>::value_type> hasher;
for ( ; cur != end ; ++cur) {
hash_combine(hash, hasher(*cur));
}
return hash;
}
} // namespace liberate::cpp
#endif // guard