11 #ifndef __TUPLE_HASH_H__
12 #define __TUPLE_HASH_H__
25 std::size_t hash_combine(std::size_t seed,
const T& v) {
26 return seed ^ (std::hash<T>()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2));
29 template<std::
size_t INDEX>
30 struct hashvalueimpl {
31 template<
typename TUPLE>
33 static size_t apply(std::size_t seed,
const TUPLE& tuple) {
35 hashvalueimpl<INDEX-1>::apply(seed, tuple),
36 std::get<INDEX>(tuple)
42 struct hashvalueimpl<0> {
43 template<
typename TUPLE>
45 static size_t apply(std::size_t seed,
const TUPLE& tuple) {
46 return hash_combine(seed, std::get<0>(tuple));
54 template<
typename... TT>
55 struct hash<std::tuple<TT...>> {
56 template<
typename TUPLE>
57 std::size_t operator()(
const TUPLE& tuple)
const {
59 return hashvalueimpl<std::tuple_size<TUPLE>::value - 1>::apply(seed, tuple);
85 template<
typename Derived>
87 const Derived&
asDerived()
const {
return *
static_cast<const Derived*
>(
this); }
88 Derived&
asDerived() {
return *
static_cast< Derived*
>(
this); }
90 bool operator==(
const Derived& rhs)
const {
return asDerived().asTuple() == rhs.asTuple(); }
91 bool operator<(
const Derived& rhs)
const {
return asDerived().asTuple() < rhs.asTuple(); }
93 struct Hash { std::size_t
operator()(
const Derived& d)
const {
104 template<
typename... CArgs>
106 using Base = std::tuple<CArgs...>;
108 template<
typename Arg>
113 template<
typename Arg1,
typename... Args>
114 ImplicitTuple(Arg1&& arg1, Args&&... args) :
Base(std::forward<Arg1>(arg1), std::forward<Args>(args)...) { }
117 using Base::operator=;