16 #ifndef C4PuncherHash_H
17 #define C4PuncherHash_H
24 size_t hash_combiner(
size_t left,
size_t right)
27 template<
int index,
class...types>
29 size_t operator()(
size_t a,
const std::tuple<types...>& t)
const {
30 typedef typename std::tuple_element<index-1, std::tuple<types...>>
::type nexttype;
31 hash_impl<index-1, types...> next;
32 size_t b = std::hash<nexttype>()(std::get<index-1>(t));
33 return next(hash_combiner(
a,
b), t);
36 template<
class...types>
37 struct hash_impl<1, types...> {
38 size_t operator()(
size_t a,
const std::tuple<types...>& t)
const {
39 typedef typename std::tuple_element<0, std::tuple<types...>>
::type nexttype;
40 size_t b = std::hash<nexttype>()(std::get<0>(t));
41 return hash_combiner(
a,
b);
44 template<
class...types>
45 struct hash_impl<0, types...> {
46 size_t operator()(
size_t a,
const std::tuple<types...>& t)
const {
54 template<
class...types>
55 struct hash<
std::tuple<types...>> {
57 const size_t begin = std::tuple_size<std::tuple<types...>>::value;
58 return hash_impl<begin, types...>()(19739, t);
69 sockaddr_in v4 = addr;
70 auto unpack = make_tuple(v4.sin_family, v4.sin_addr.s_addr, v4.sin_port);
71 return hash<decltype(unpack)>()(unpack);
75 sockaddr_in6 v6 = addr;
76 auto unpack = make_tuple(v6.sin6_family, v6.sin6_port, v6.sin6_flowinfo, std::string((
char*) v6.sin6_addr.s6_addr, 16), v6.sin6_scope_id);
77 return hash<decltype(unpack)>()(unpack);
80 assert(!
"Unexpected address family");
AddressFamily GetFamily() const
size_t operator()(const C4NetIO::addr_t &addr) const
size_t operator()(const std::tuple< types... > &t) const