xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
include
xrpl
beast
hash
hash_append.h
1
#pragma once
2
3
#include <boost/container/flat_set.hpp>
4
#include <boost/endian/conversion.hpp>
5
6
#include <
array
>
7
#include <
chrono
>
8
#include <
cstddef
>
9
#include <
cstring
>
10
#include <
memory
>
11
#include <
string
>
12
#include <
system_error
>
13
#include <
tuple
>
14
#include <
type_traits
>
15
#include <
unordered_map
>
16
#include <
unordered_set
>
17
#include <
utility
>
18
#include <
vector
>
19
20
namespace
beast
{
21
22
namespace
detail
{
23
24
template
<
class
T>
25
/*constexpr*/
26
inline
void
27
reverseBytes
(T& t)
28
{
29
auto
* bytes =
30
static_cast<
unsigned
char
*
>
(
std::memmove
(
std::addressof
(t),
std::addressof
(t),
sizeof
(T)));
31
for
(
unsigned
i = 0; i <
sizeof
(T) / 2; ++i)
32
std::swap
(bytes[i], bytes[
sizeof
(T) - 1 - i]);
33
}
34
35
template
<
class
T>
36
/*constexpr*/
37
inline
void
38
maybeReverseBytes
(T& t,
std::false_type
)
39
{
40
}
41
42
template
<
class
T>
43
/*constexpr*/
44
inline
void
45
maybeReverseBytes
(T& t,
std::true_type
)
46
{
47
reverse_bytes(t);
48
}
49
50
template
<
class
T,
class
Hasher>
51
/*constexpr*/
52
inline
void
53
maybeReverseBytes
(T& t, Hasher&)
54
{
55
maybeReverseBytes
(
56
t,
std::integral_constant<bool, Hasher::kEndian != boost::endian::order::native>
{});
57
}
58
59
}
// namespace detail
60
61
// IsUniquelyRepresented<T>
62
63
// A type T is contiguously hashable if for all combinations of two values of
64
// a type, say x and y, if x == y, then it must also be true that
65
// memcmp(addressof(x), addressof(y), sizeof(T)) == 0. I.e. if x == y,
66
// then x and y have the same bit pattern representation.
67
68
template
<
class
T>
69
struct
IsUniquelyRepresented
70
:
public
std::integral_constant
<
71
bool,
72
std::is_integral_v<T> || std::is_enum_v<T> || std::is_pointer_v<T>>
73
{
74
explicit
IsUniquelyRepresented
() =
default
;
75
};
76
77
template
<
class
T>
78
struct
IsUniquelyRepresented
<T const> :
public
IsUniquelyRepresented
<T>
79
{
80
explicit
IsUniquelyRepresented
() =
default
;
81
};
82
83
template
<
class
T>
84
struct
IsUniquelyRepresented
<T volatile> :
public
IsUniquelyRepresented
<T>
85
{
86
explicit
IsUniquelyRepresented
() =
default
;
87
};
88
89
template
<
class
T>
90
struct
IsUniquelyRepresented
<T const volatile> :
public
IsUniquelyRepresented
<T>
91
{
92
explicit
IsUniquelyRepresented
() =
default
;
93
};
94
95
// IsUniquelyRepresented<std::pair<T, U>>
96
97
template
<
class
T,
class
U>
98
struct
IsUniquelyRepresented
<
std
::pair<T, U>>
99
:
public
std::integral_constant
<
100
bool,
101
IsUniquelyRepresented<T>::value && IsUniquelyRepresented<U>::value &&
102
sizeof(T) + sizeof(U) == sizeof(std::pair<T, U>)>
103
{
104
explicit
IsUniquelyRepresented
() =
default
;
105
};
106
107
// IsUniquelyRepresented<std::tuple<T...>>
108
109
template
<
class
... T>
110
struct
IsUniquelyRepresented
<
std
::tuple<T...>>
111
:
public
std::integral_constant
<
112
bool,
113
std::conjunction_v<IsUniquelyRepresented<T>...> &&
114
sizeof(std::tuple<T...>) == (sizeof(T) + ...)>
115
{
116
explicit
IsUniquelyRepresented
() =
default
;
117
};
118
119
// IsUniquelyRepresented<T[N]>
120
121
template
<
class
T, std::
size_t
N>
122
struct
IsUniquelyRepresented
<T[N]> :
public
IsUniquelyRepresented
<T>
123
{
124
explicit
IsUniquelyRepresented
() =
default
;
125
};
126
127
// IsUniquelyRepresented<std::array<T, N>>
128
129
template
<
class
T, std::
size_t
N>
130
struct
IsUniquelyRepresented
<
std
::array<T, N>>
131
:
public
std::integral_constant
<
132
bool,
133
IsUniquelyRepresented<T>::value && sizeof(T) * N == sizeof(std::array<T, N>)>
134
{
135
explicit
IsUniquelyRepresented
() =
default
;
136
};
137
153
template
<
class
T,
class
HashAlgorithm>
154
struct
IsContiguouslyHashable
155
:
public
std::integral_constant
<
156
bool,
157
IsUniquelyRepresented<T>::value &&
158
(sizeof(T) == 1 || HashAlgorithm::kEndian == boost::endian::order::native)>
159
{
160
explicit
IsContiguouslyHashable
() =
default
;
161
};
162
163
template
<
class
T, std::
size_t
N,
class
HashAlgorithm>
164
struct
IsContiguouslyHashable
<T[N], HashAlgorithm>
165
:
public
std::integral_constant
<
166
bool,
167
IsUniquelyRepresented<T[N]>::value &&
168
(sizeof(T) == 1 || HashAlgorithm::endian == boost::endian::order::native)>
169
{
170
explicit
IsContiguouslyHashable
() =
default
;
171
};
172
173
174
//------------------------------------------------------------------------------
175
201
202
// scalars
203
204
template
<
class
Hasher,
class
T>
205
inline
void
206
hash_append
(Hasher& h, T
const
& t)
noexcept
207
requires
(
IsContiguouslyHashable<T, Hasher>::value
)
208
{
209
// NOLINTNEXTLINE(bugprone-sizeof-expression)
210
h(
static_cast<
void
const*
>
(
std::addressof
(t)),
sizeof
(t));
211
}
212
213
template
<
class
Hasher,
class
T>
214
inline
void
215
hash_append
(Hasher& h, T t)
noexcept
216
requires
(
217
!
IsContiguouslyHashable<T, Hasher>::value
&&
218
(
std::is_integral_v<T>
||
std::is_pointer_v<T>
||
std::is_enum_v<T>
))
219
{
220
detail::reverseBytes
(t);
221
h(
std::addressof
(t),
sizeof
(t));
222
}
223
224
template
<
class
Hasher,
class
T>
225
inline
void
226
hash_append
(Hasher& h, T t)
noexcept
227
requires
(
std::is_floating_point_v<T>
)
228
{
229
if
(t == 0)
230
t = 0;
231
detail::maybeReverseBytes
(t, h);
232
h(&t,
sizeof
(t));
233
}
234
235
template
<
class
Hasher>
236
inline
void
237
hash_append
(Hasher& h,
std::nullptr_t
)
noexcept
238
{
239
void
const
* p =
nullptr
;
240
detail::maybeReverseBytes
(p, h);
241
h(&p,
sizeof
(p));
242
}
243
244
// Forward declarations for ADL purposes
245
246
template
<
class
Hasher,
class
T, std::
size_t
N>
247
void
248
hash_append
(Hasher& h, T (&a)[N])
noexcept
249
requires
(!IsContiguouslyHashable<T, Hasher>::value);
250
251
template
<
class
Hasher,
class
CharT,
class
Traits,
class
Alloc>
252
void
253
hash_append
(Hasher& h,
std::basic_string<CharT, Traits, Alloc>
const
& s)
noexcept
254
requires
(!IsContiguouslyHashable<CharT, Hasher>::value);
255
256
template
<
class
Hasher,
class
CharT,
class
Traits,
class
Alloc>
257
void
258
hash_append
(Hasher& h,
std::basic_string<CharT, Traits, Alloc>
const
& s)
noexcept
259
requires
(IsContiguouslyHashable<CharT, Hasher>::value);
260
261
template
<
class
Hasher,
class
T,
class
U>
262
void
263
hash_append
(Hasher& h,
std::pair<T, U>
const
& p)
noexcept
264
requires
(!IsContiguouslyHashable<std::pair<T, U>, Hasher>::value);
265
266
template
<
class
Hasher,
class
T,
class
Alloc>
267
void
268
hash_append
(Hasher& h,
std::vector<T, Alloc>
const
& v)
noexcept
269
requires
(!IsContiguouslyHashable<T, Hasher>::value);
270
271
template
<
class
Hasher,
class
T,
class
Alloc>
272
void
273
hash_append
(Hasher& h,
std::vector<T, Alloc>
const
& v)
noexcept
274
requires
(IsContiguouslyHashable<T, Hasher>::value);
275
276
template
<
class
Hasher,
class
T, std::
size_t
N>
277
void
278
hash_append
(Hasher& h,
std::array<T, N>
const
& a)
noexcept
279
requires
(!IsContiguouslyHashable<std::array<T, N>, Hasher>::value);
280
281
template
<
class
Hasher,
class
... T>
282
void
283
hash_append
(Hasher& h,
std::tuple<T...>
const
& t)
noexcept
284
requires
(!IsContiguouslyHashable<
std::tuple
<T...>, Hasher>::value);
285
286
template
<
class
Hasher,
class
Key,
class
T,
class
Hash,
class
Pred,
class
Alloc>
287
void
288
hash_append
(Hasher& h,
std::unordered_map<Key, T, Hash, Pred, Alloc>
const
& m);
289
290
template
<
class
Hasher,
class
Key,
class
Hash,
class
Pred,
class
Alloc>
291
void
292
hash_append
(Hasher& h,
std::unordered_set<Key, Hash, Pred, Alloc>
const
& s);
293
294
template
<
class
Hasher,
class
Key,
class
Compare,
class
Alloc>
295
void
296
hash_append
(Hasher& h, boost::container::flat_set<Key, Compare, Alloc>
const
& v)
noexcept
297
requires
(!
IsContiguouslyHashable<Key, Hasher>::value
);
298
template
<
class
Hasher,
class
Key,
class
Compare,
class
Alloc>
299
void
300
hash_append
(Hasher& h, boost::container::flat_set<Key, Compare, Alloc>
const
& v)
noexcept
301
requires
(
IsContiguouslyHashable<Key, Hasher>::value
);
302
template
<
class
Hasher,
class
T0,
class
T1,
class
... T>
303
void
304
hash_append
(Hasher& h, T0
const
& t0, T1
const
& t1, T
const
&... t)
noexcept
;
305
306
// c-array
307
308
template
<
class
Hasher,
class
T, std::
size_t
N>
309
void
310
hash_append
(Hasher& h, T (&a)[N])
noexcept
311
requires
(!
IsContiguouslyHashable<T, Hasher>::value
)
312
{
313
for
(
auto
const
& t : a)
314
hash_append
(h, t);
315
}
316
317
// basic_string
318
319
template
<
class
Hasher,
class
CharT,
class
Traits,
class
Alloc>
320
inline
void
321
hash_append
(Hasher& h,
std::basic_string<CharT, Traits, Alloc>
const
& s)
noexcept
322
requires
(!
IsContiguouslyHashable<CharT, Hasher>::value
)
323
{
324
for
(
auto
c : s)
325
hash_append
(h, c);
326
hash_append
(h, s.size());
327
}
328
329
template
<
class
Hasher,
class
CharT,
class
Traits,
class
Alloc>
330
inline
void
331
hash_append
(Hasher& h,
std::basic_string<CharT, Traits, Alloc>
const
& s)
noexcept
332
requires
(
IsContiguouslyHashable<CharT, Hasher>::value
)
333
{
334
h(s.data(), s.size() *
sizeof
(CharT));
335
hash_append
(h, s.size());
336
}
337
338
// pair
339
340
template
<
class
Hasher,
class
T,
class
U>
341
inline
void
342
hash_append
(Hasher& h,
std::pair<T, U>
const
& p)
noexcept
343
requires
(!
IsContiguouslyHashable<std::pair<T, U>
, Hasher>::value)
344
{
345
hash_append
(h, p.first, p.second);
346
}
347
348
// vector
349
350
template
<
class
Hasher,
class
T,
class
Alloc>
351
inline
void
352
hash_append
(Hasher& h,
std::vector<T, Alloc>
const
& v)
noexcept
353
requires
(!
IsContiguouslyHashable<T, Hasher>::value
)
354
{
355
for
(
auto
const
& t : v)
356
hash_append
(h, t);
357
hash_append
(h, v.size());
358
}
359
360
template
<
class
Hasher,
class
T,
class
Alloc>
361
inline
void
362
hash_append
(Hasher& h,
std::vector<T, Alloc>
const
& v)
noexcept
363
requires
(
IsContiguouslyHashable<T, Hasher>::value
)
364
{
365
h(v.data(), v.size() *
sizeof
(T));
366
hash_append
(h, v.size());
367
}
368
369
// array
370
371
template
<
class
Hasher,
class
T, std::
size_t
N>
372
void
373
hash_append
(Hasher& h,
std::array<T, N>
const
& a)
noexcept
374
requires
(!
IsContiguouslyHashable<std::array<T, N>
, Hasher>::value)
375
{
376
for
(
auto
const
& t : a)
377
hash_append
(h, t);
378
}
379
380
template
<
class
Hasher,
class
Key,
class
Compare,
class
Alloc>
381
void
382
hash_append
(Hasher& h, boost::container::flat_set<Key, Compare, Alloc>
const
& v)
noexcept
383
requires
(!
IsContiguouslyHashable<Key, Hasher>::value
)
384
{
385
for
(
auto
const
& t : v)
386
hash_append
(h, t);
387
}
388
template
<
class
Hasher,
class
Key,
class
Compare,
class
Alloc>
389
void
390
hash_append
(Hasher& h, boost::container::flat_set<Key, Compare, Alloc>
const
& v)
noexcept
391
requires
(
IsContiguouslyHashable<Key, Hasher>::value
)
392
{
393
h(&(v.begin()), v.size() *
sizeof
(Key));
394
}
395
// tuple
396
397
template
<
class
Hasher,
class
... T>
398
inline
void
399
hash_append
(Hasher& h,
std::tuple<T...>
const
& t)
noexcept
400
requires
(!
IsContiguouslyHashable
<
std::tuple
<T...>, Hasher>::value)
401
{
402
std::apply
([&h](
auto
const
&... item) { (
hash_append
(h, item), ...); }, t);
403
}
404
405
// shared_ptr
406
407
template
<
class
Hasher,
class
T>
408
inline
void
409
hash_append
(Hasher& h,
std::shared_ptr<T>
const
& p)
noexcept
410
{
411
hash_append
(h, p.get());
412
}
413
414
// chrono
415
416
template
<
class
Hasher,
class
Rep,
class
Period>
417
inline
void
418
hash_append
(Hasher& h,
std::chrono::duration<Rep, Period>
const
& d)
noexcept
419
{
420
hash_append
(h, d.count());
421
}
422
423
template
<
class
Hasher,
class
Clock,
class
Duration>
424
inline
void
425
hash_append
(Hasher& h,
std::chrono::time_point<Clock, Duration>
const
& tp)
noexcept
426
{
427
hash_append
(h, tp.time_since_epoch());
428
}
429
430
// variadic
431
432
template
<
class
Hasher,
class
T0,
class
T1,
class
... T>
433
inline
void
434
hash_append
(Hasher& h, T0
const
& t0, T1
const
& t1, T
const
&... t)
noexcept
435
{
436
hash_append
(h, t0);
437
hash_append
(h, t1, t...);
438
}
439
440
// error_code
441
442
template
<
class
HashAlgorithm>
443
inline
void
444
hash_append
(HashAlgorithm& h,
std::error_code
const
& ec)
445
{
446
hash_append
(h, ec.
value
(), &ec.
category
());
447
}
448
449
}
// namespace beast
std::addressof
T addressof(T... args)
std::apply
T apply(T... args)
array
std::basic_string
std::error_code::category
T category(T... args)
chrono
cstddef
cstring
std::chrono::duration
std::error_code
std::false_type
std::is_enum_v
T is_enum_v
std::is_floating_point_v
T is_floating_point_v
std::is_integral_v
T is_integral_v
std::is_pointer_v
T is_pointer_v
std::memmove
T memmove(T... args)
memory
beast::detail
Definition
abstract_clock.h:59
beast::detail::reverseBytes
void reverseBytes(T &t)
Definition
hash_append.h:27
beast::detail::maybeReverseBytes
void maybeReverseBytes(T &t, std::false_type)
Definition
hash_append.h:38
beast
Definition
base_uint.h:697
beast::hash_append
void hash_append(Hasher &h, T const &t) noexcept
Logically concatenate input data to a Hasher.
Definition
hash_append.h:206
std
STL namespace.
std::nullptr_t
std::pair
std::shared_ptr
string
beast::IsContiguouslyHashable< T[N], HashAlgorithm >::IsContiguouslyHashable
IsContiguouslyHashable()=default
beast::IsContiguouslyHashable
Metafunction returning true if the type can be hashed in one call.
Definition
hash_append.h:159
beast::IsContiguouslyHashable::IsContiguouslyHashable
IsContiguouslyHashable()=default
beast::IsUniquelyRepresented< T const >::IsUniquelyRepresented
IsUniquelyRepresented()=default
beast::IsUniquelyRepresented< T const volatile >::IsUniquelyRepresented
IsUniquelyRepresented()=default
beast::IsUniquelyRepresented< T volatile >::IsUniquelyRepresented
IsUniquelyRepresented()=default
beast::IsUniquelyRepresented< T[N]>::IsUniquelyRepresented
IsUniquelyRepresented()=default
beast::IsUniquelyRepresented< std::array< T, N > >::IsUniquelyRepresented
IsUniquelyRepresented()=default
beast::IsUniquelyRepresented< std::pair< T, U > >::IsUniquelyRepresented
IsUniquelyRepresented()=default
beast::IsUniquelyRepresented< std::tuple< T... > >::IsUniquelyRepresented
IsUniquelyRepresented()=default
beast::IsUniquelyRepresented::IsUniquelyRepresented
IsUniquelyRepresented()=default
std::swap
T swap(T... args)
system_error
std::chrono::time_point
tuple
type_traits
unordered_map
unordered_set
utility
std::error_code::value
T value(T... args)
vector
Generated by
1.17.0