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