10
10
#ifndef BOOST_JSON_DETAIL_DIGEST_HPP
11
11
#define BOOST_JSON_DETAIL_DIGEST_HPP
12
12
13
+ #include < algorithm>
14
+ #include < array>
15
+ #include < cstring>
16
+
13
17
namespace boost {
14
18
namespace json {
15
19
namespace detail {
@@ -23,15 +27,40 @@ digest(
23
27
std::size_t salt) noexcept
24
28
{
25
29
#if BOOST_JSON_ARCH == 64
26
- std::uint64_t const prime = 0x100000001B3ULL ;
27
- std::uint64_t hash = 0xcbf29ce484222325ULL ;
30
+ using hash_t = std::uint64_t ;
31
+ hash_t const prime = 0x100000001B3ULL ;
32
+ hash_t hash = 0xcbf29ce484222325ULL ;
28
33
#else
29
- std::uint32_t const prime = 0x01000193UL ;
30
- std::uint32_t hash = 0x811C9DC5UL ;
34
+ using hash_t = std::uint32_t ;
35
+ hash_t const prime = 0x01000193UL ;
36
+ hash_t hash = 0x811C9DC5UL ;
31
37
#endif
32
38
hash += salt;
33
- for (; b != e; ++b)
34
- hash = (*b ^ hash) * prime;
39
+
40
+ constexpr std::size_t step = sizeof (hash_t );
41
+ std::size_t n = std::distance (b, e);
42
+ std::size_t const m = n % step;
43
+
44
+ char temp[step];
45
+ while ( n > m )
46
+ {
47
+ std::copy_n (b, step, temp);
48
+
49
+ hash_t batch;
50
+ std::memcpy (&batch, temp, step);
51
+ hash = (batch ^ hash) * prime;
52
+
53
+ std::advance (b, step);
54
+ n -= step;
55
+ }
56
+
57
+ std::memset (temp, 0 , step);
58
+ std::copy_n (b, n, temp);
59
+
60
+ hash_t batch;
61
+ std::memcpy (&batch, temp, step);
62
+ hash = (batch ^ hash) * prime;
63
+
35
64
return hash;
36
65
}
37
66
0 commit comments