ttg 1.0.0-alpha
Template Task Graph (TTG): flowgraph-based programming model for high-performance distributed-memory algorithms
Loading...
Searching...
No Matches
hash.h
Go to the documentation of this file.
1#ifndef TTG_UTIL_HASH_H
2#define TTG_UTIL_HASH_H
3
4#include <cstddef>
5#include <cstdint>
6
7#include "ttg/util/void.h"
8
9namespace ttg {
10 namespace detail {
12 class FNVhasher {
13 // https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
14 using result_type = std::size_t;
15 static const result_type offset_basis = 14695981039346656037ul;
16 static const result_type prime = 1099511628211ul;
17 result_type value_ = offset_basis;
18
19 public:
22 void update(std::byte byte) noexcept { value_ = (value_ ^ static_cast<uint_fast8_t>(byte)) * prime; }
23
25 void update(size_t n, const std::byte* bytes) noexcept {
26 for (size_t i = 0; i < n; i++) update(bytes[i]);
27 }
28
30 auto value() const noexcept { return value_; }
31
33 static result_type initial_value() { return offset_basis; }
34 };
35
38 static_assert(sizeof(std::size_t) == sizeof(std::uint64_t));
39
40 inline static std::size_t fn(std::size_t h, std::size_t k) {
41 const std::size_t m = (std::size_t(0xc6a4a793) << 32) + 0x5bd1e995;
42 const int r = 47;
43
44 k *= m;
45 k ^= k >> r;
46 k *= m;
47
48 h ^= k;
49 h *= m;
50
51 // Completely arbitrary number, to prevent 0's
52 // from hashing to 0.
53 h += 0xe6546b64;
54
55 return h;
56 }
57 };
58
59 } // namespace detail
60
61 namespace meta {
63 // has_member_function_hash_v<T> evaluates to true if T::hash() is defined
65 template <typename T, typename Enabler = void>
66 struct has_member_function_hash : std::false_type {};
67 template <typename T>
68 struct has_member_function_hash<T, std::void_t<decltype(std::declval<const T&>().hash())>> : std::true_type {};
69 template <typename T>
71 } // namespace meta
72
74 namespace overload {
75
77
80 template <typename T, typename Enabler = void>
81 struct hash;
82
84 template <typename T>
85 struct hash<T, std::enable_if_t<meta::has_member_function_hash_v<T>>> {
86 auto operator()(const T& t) const { return t.hash(); }
87 };
88
90 template <>
91 struct hash<void, void> {
93 // convenient to be able to hash Void using hash<void>
94 auto operator()(const ttg::Void&) const { return operator()(); }
95 };
96
98 template <>
99 struct hash<Void, void> {
100 auto operator()(const ttg::Void&) const { return hash<void>{}(); }
101 };
102
104 template <typename T>
105 struct hash<T, std::enable_if_t<std::is_integral_v<std::decay_t<T>> && sizeof(T) <= sizeof(std::size_t), void>> {
106 auto operator()(T t) const { return static_cast<std::size_t>(t); }
107 };
108
111 template <typename T>
112 struct hash<
113 T, std::enable_if_t<!(std::is_integral_v<std::decay_t<T>> && sizeof(T) <= sizeof(std::size_t)) &&
114 !(meta::has_member_function_hash_v<T>)&&std::has_unique_object_representations_v<T>,
115 void>> {
116 auto operator()(const T& t) const {
117 detail::FNVhasher hasher;
118 hasher.update(sizeof(T), reinterpret_cast<const std::byte*>(&t));
119 return hasher.value();
120 }
121 };
122
124 template <typename T, typename Enabler>
125 struct hash {
126 constexpr static bool NEED_TO_PROVIDE_SPECIALIZATION_OF_TTG_OVERLOAD_HASH_FOR_THIS_TYPE = !std::is_same_v<T, T>;
127 static_assert(NEED_TO_PROVIDE_SPECIALIZATION_OF_TTG_OVERLOAD_HASH_FOR_THIS_TYPE);
128 };
129 } // namespace overload
130
131 using namespace ttg::overload;
132
133 namespace meta {
135 // has_ttg_hash_specialization_v<T> evaluates to true if ttg::hash<T> is defined
137 template <typename T, typename Enabler = void>
138 struct has_ttg_hash_specialization : std::false_type {};
139 template <typename T>
141 T, ttg::meta::void_t<decltype(std::declval<ttg::hash<T>>()(std::declval<const T&>()))>> : std::true_type {};
142 template <typename T>
144 } // namespace meta
145
146 template <class T>
147 inline void hash_combine(std::size_t& seed, T const& v) {
148 ttg::hash<T> hasher;
149 seed = detail::hash_combine_impl::fn(seed, hasher(v));
150 }
151
152} // namespace ttg
153
154
156
157#endif // TTG_UTIL_HASH_H
A complete version of void.
Definition void.h:11
byte-wise hasher
Definition hash.h:12
void update(size_t n, const std::byte *bytes) noexcept
Updates the hash with an additional n bytes.
Definition hash.h:25
static result_type initial_value()
Definition hash.h:33
auto value() const noexcept
Definition hash.h:30
void update(std::byte byte) noexcept
Definition hash.h:22
STL namespace.
constexpr bool has_member_function_hash_v
Definition hash.h:70
void void_t
Definition meta.h:20
constexpr bool has_ttg_hash_specialization_v
Definition hash.h:143
place for overloading/instantiating hash and other functionality
Definition hash.h:74
top-level TTG namespace contains runtime-neutral functionality
Definition keymap.h:8
void hash_combine(std::size_t &seed, T const &v)
Definition hash.h:147
combines 2 hash values; implementation based on boost::hash_combine_impl<64> from Boost v1....
Definition hash.h:37
static std::size_t fn(std::size_t h, std::size_t k)
Definition hash.h:40
auto operator()(const ttg::Void &) const
Definition hash.h:100
auto operator()(const ttg::Void &) const
Definition hash.h:94
Computes hash values for objects of type T.
Definition hash.h:81