In a C++ program with Boost, I am trying to build an unordered map whose keys are tuples of doubles:
typedef boost::tuples::tuple
This code from Generic hash for tuples in unordered_map / unordered_set provides magical support for all c++11 tuples of standard hashable types (strings, ints etc).
Unsurprisingly it looks very much like Matthieu M.'s solution above but with no boost dependencies.
Put the code in a header file and include it and unordered sets of tuples will work out of the box:
#include
namespace std{
namespace
{
// Code from boost
// Reciprocal of the golden ratio helps spread entropy
// and handles duplicates.
// See Mike Seymour in magic-numbers-in-boosthash-combine:
// https://stackoverflow.com/questions/4948780
template
inline void hash_combine(std::size_t& seed, T const& v)
{
seed ^= hash()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
// Recursive template code derived from Matthieu M.
template ::value - 1>
struct HashValueImpl
{
static void apply(size_t& seed, Tuple const& tuple)
{
HashValueImpl::apply(seed, tuple);
hash_combine(seed, get(tuple));
}
};
template
struct HashValueImpl
{
static void apply(size_t& seed, Tuple const& tuple)
{
hash_combine(seed, get<0>(tuple));
}
};
}
template
struct hash>
{
size_t
operator()(std::tuple const& tt) const
{
size_t seed = 0;
HashValueImpl >::apply(seed, tt);
return seed;
}
};
}