-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtuple_helper.h
More file actions
69 lines (60 loc) · 1.91 KB
/
tuple_helper.h
File metadata and controls
69 lines (60 loc) · 1.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#pragma once
#include <tuple>
namespace tuple_helper {
template <class type_tt>
void hash_impl(std::size_t& offset, const type_tt& key) {
std::hash<type_tt> hasher;
offset ^= hasher(key) + 0x9e3779b9 + (offset << 6) + (offset >> 2);
}
}; // namespace tuple_helper
namespace std {
template <class... args_tt>
struct hash<std::tuple<args_tt...>> {
template <class tuple_tt,
std::size_t index = std::tuple_size<tuple_tt>::value - 1>
struct impl {
static void apply(std::size_t& offset, const tuple_tt& tuple) {
impl<tuple_tt, index - 1>::apply(offset, tuple);
tuple_helper::hash_impl(offset, std::get<index>(tuple));
}
};
template <class tuple_tt>
struct impl<tuple_tt, 0> {
static void apply(std::size_t& offset, const tuple_tt& tuple) {
tuple_helper::hash_impl(offset, std::get<0>(tuple));
}
};
std::size_t operator()(const std::tuple<args_tt...>& key) const {
std::size_t offset = 0;
impl<std::tuple<args_tt...>>::apply(offset, key);
return offset;
}
};
}; // end namespace std
namespace tuple_helper {
struct printer {
template <class ostream_tt, class tuple_tt,
size_t index = std::tuple_size<tuple_tt>::value - 1>
struct impl {
static void apply(ostream_tt& ostr, const tuple_tt& tuple) {
impl<ostream_tt, tuple_tt, index - 1>::apply(ostr, tuple);
ostr << "," << std::get<index>(tuple);
}
};
template <class ostream_tt, class tuple_tt>
struct impl<ostream_tt, tuple_tt, 0> {
static void apply(ostream_tt& ostr, const tuple_tt& tuple) {
ostr << std::get<0>(tuple);
}
};
};
}; // namespace tuple_helper
template <class ostream_tt, class... args_tt>
ostream_tt& operator<<(ostream_tt& ostr,
const std::tuple<args_tt...>& tuple_value) {
ostr << "(";
tuple_helper::printer::impl<ostream_tt, std::tuple<args_tt...>>::apply(
ostr, tuple_value);
ostr << ")";
return ostr;
}