/src/boost/boost/json/detail/digest.hpp
Line | Count | Source |
1 | | // |
2 | | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) |
3 | | // |
4 | | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5 | | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | | // |
7 | | // Official repository: https://github.com/boostorg/json |
8 | | // |
9 | | |
10 | | #ifndef BOOST_JSON_DETAIL_DIGEST_HPP |
11 | | #define BOOST_JSON_DETAIL_DIGEST_HPP |
12 | | |
13 | | #include <boost/json/detail/config.hpp> |
14 | | |
15 | | #include <algorithm> |
16 | | #include <iterator> |
17 | | |
18 | | namespace boost { |
19 | | namespace json { |
20 | | namespace detail { |
21 | | |
22 | | // Calculate salted digest of string |
23 | | template<class ForwardIterator> |
24 | | std::size_t |
25 | | digest(ForwardIterator b, ForwardIterator e, std::size_t salt) noexcept |
26 | 1.48M | { |
27 | 1.48M | std::size_t const len = std::distance(b, e); |
28 | | |
29 | 1.48M | #if BOOST_JSON_ARCH == 64 |
30 | | |
31 | 1.48M | using state_type = std::uint64_t; |
32 | 1.48M | state_type const m = 0xc6a4a7935bd1e995ULL; |
33 | 1.48M | int const r = 47; |
34 | 1.48M | state_type hash = salt ^ (len * m); |
35 | | |
36 | 1.48M | constexpr std::size_t N = sizeof(state_type); |
37 | 1.48M | e = std::next( b, len & ~std::size_t(N-1) ); |
38 | 2.67M | for( ; b != e; std::advance(b, N) ) |
39 | 1.19M | { |
40 | 1.19M | state_type num; |
41 | | #ifdef _MSC_VER |
42 | | # pragma warning(push) |
43 | | # pragma warning(disable: 4996) |
44 | | #endif |
45 | 1.19M | std::copy_n( b, N, reinterpret_cast<unsigned char*>(&num) ); |
46 | | #ifdef _MSC_VER |
47 | | # pragma warning(pop) |
48 | | #endif |
49 | | |
50 | 1.19M | num *= m; |
51 | 1.19M | num ^= num >> r; |
52 | 1.19M | num *= m; |
53 | 1.19M | hash ^= num; |
54 | 1.19M | hash *= m; |
55 | 1.19M | } |
56 | | |
57 | 1.48M | switch( len & (N - 1) ) |
58 | 1.48M | { |
59 | 22.6k | case 7: hash ^= state_type( *std::next(b, 6) ) << 48; // fall through |
60 | 71.4k | case 6: hash ^= state_type( *std::next(b, 5) ) << 40; // fall through |
61 | 112k | case 5: hash ^= state_type( *std::next(b, 4) ) << 32; // fall through |
62 | 167k | case 4: hash ^= state_type( *std::next(b, 3) ) << 24; // fall through |
63 | 230k | case 3: hash ^= state_type( *std::next(b, 2) ) << 16; // fall through |
64 | 298k | case 2: hash ^= state_type( *std::next(b, 1) ) << 8; // fall through |
65 | 365k | case 1: hash ^= state_type( *std::next(b, 0) ); |
66 | 365k | hash *= m; |
67 | 1.48M | }; |
68 | | |
69 | 1.48M | hash ^= hash >> r; |
70 | 1.48M | hash *= m; |
71 | 1.48M | hash ^= hash >> r; |
72 | | |
73 | | #else |
74 | | |
75 | | using state_type = std::uint32_t; |
76 | | state_type const m = 0x5bd1e995; |
77 | | int const r = 24; |
78 | | state_type hash = salt ^ len; |
79 | | |
80 | | constexpr std::size_t N = sizeof(state_type); |
81 | | e = std::next( b, len & ~std::size_t(N-1) ); |
82 | | for( ; b != e; std::advance(b, N) ) |
83 | | { |
84 | | state_type num; |
85 | | std::copy_n( b, N, reinterpret_cast<unsigned char*>(&num) ); |
86 | | |
87 | | num *= m; |
88 | | num ^= num >> r; |
89 | | num *= m; |
90 | | hash *= m; |
91 | | hash ^= num; |
92 | | } |
93 | | |
94 | | switch( len & (N - 1) ) |
95 | | { |
96 | | case 3: hash ^= state_type( *std::next(b, 2) ) << 16; // fall through |
97 | | case 2: hash ^= state_type( *std::next(b, 1) ) << 8; // fall through |
98 | | case 1: hash ^= state_type( *std::next(b, 0) ); |
99 | | hash *= m; |
100 | | }; |
101 | | |
102 | | hash ^= hash >> 13; |
103 | | hash *= m; |
104 | | hash ^= hash >> 15; |
105 | | |
106 | | #endif |
107 | | |
108 | 1.48M | return hash; |
109 | 1.48M | } unsigned long boost::json::detail::digest<char const*>(char const*, char const*, unsigned long) Line | Count | Source | 26 | 1.48M | { | 27 | 1.48M | std::size_t const len = std::distance(b, e); | 28 | | | 29 | 1.48M | #if BOOST_JSON_ARCH == 64 | 30 | | | 31 | 1.48M | using state_type = std::uint64_t; | 32 | 1.48M | state_type const m = 0xc6a4a7935bd1e995ULL; | 33 | 1.48M | int const r = 47; | 34 | 1.48M | state_type hash = salt ^ (len * m); | 35 | | | 36 | 1.48M | constexpr std::size_t N = sizeof(state_type); | 37 | 1.48M | e = std::next( b, len & ~std::size_t(N-1) ); | 38 | 2.67M | for( ; b != e; std::advance(b, N) ) | 39 | 1.19M | { | 40 | 1.19M | state_type num; | 41 | | #ifdef _MSC_VER | 42 | | # pragma warning(push) | 43 | | # pragma warning(disable: 4996) | 44 | | #endif | 45 | 1.19M | std::copy_n( b, N, reinterpret_cast<unsigned char*>(&num) ); | 46 | | #ifdef _MSC_VER | 47 | | # pragma warning(pop) | 48 | | #endif | 49 | | | 50 | 1.19M | num *= m; | 51 | 1.19M | num ^= num >> r; | 52 | 1.19M | num *= m; | 53 | 1.19M | hash ^= num; | 54 | 1.19M | hash *= m; | 55 | 1.19M | } | 56 | | | 57 | 1.48M | switch( len & (N - 1) ) | 58 | 1.48M | { | 59 | 22.6k | case 7: hash ^= state_type( *std::next(b, 6) ) << 48; // fall through | 60 | 71.4k | case 6: hash ^= state_type( *std::next(b, 5) ) << 40; // fall through | 61 | 112k | case 5: hash ^= state_type( *std::next(b, 4) ) << 32; // fall through | 62 | 167k | case 4: hash ^= state_type( *std::next(b, 3) ) << 24; // fall through | 63 | 230k | case 3: hash ^= state_type( *std::next(b, 2) ) << 16; // fall through | 64 | 298k | case 2: hash ^= state_type( *std::next(b, 1) ) << 8; // fall through | 65 | 365k | case 1: hash ^= state_type( *std::next(b, 0) ); | 66 | 365k | hash *= m; | 67 | 1.48M | }; | 68 | | | 69 | 1.48M | hash ^= hash >> r; | 70 | 1.48M | hash *= m; | 71 | 1.48M | hash ^= hash >> r; | 72 | | | 73 | | #else | 74 | | | 75 | | using state_type = std::uint32_t; | 76 | | state_type const m = 0x5bd1e995; | 77 | | int const r = 24; | 78 | | state_type hash = salt ^ len; | 79 | | | 80 | | constexpr std::size_t N = sizeof(state_type); | 81 | | e = std::next( b, len & ~std::size_t(N-1) ); | 82 | | for( ; b != e; std::advance(b, N) ) | 83 | | { | 84 | | state_type num; | 85 | | std::copy_n( b, N, reinterpret_cast<unsigned char*>(&num) ); | 86 | | | 87 | | num *= m; | 88 | | num ^= num >> r; | 89 | | num *= m; | 90 | | hash *= m; | 91 | | hash ^= num; | 92 | | } | 93 | | | 94 | | switch( len & (N - 1) ) | 95 | | { | 96 | | case 3: hash ^= state_type( *std::next(b, 2) ) << 16; // fall through | 97 | | case 2: hash ^= state_type( *std::next(b, 1) ) << 8; // fall through | 98 | | case 1: hash ^= state_type( *std::next(b, 0) ); | 99 | | hash *= m; | 100 | | }; | 101 | | | 102 | | hash ^= hash >> 13; | 103 | | hash *= m; | 104 | | hash ^= hash >> 15; | 105 | | | 106 | | #endif | 107 | | | 108 | 1.48M | return hash; | 109 | 1.48M | } |
Unexecuted instantiation: unsigned long boost::json::detail::digest<boost::json::detail::pointer_token::iterator>(boost::json::detail::pointer_token::iterator, boost::json::detail::pointer_token::iterator, unsigned long) |
110 | | |
111 | | } // detail |
112 | | } // namespace json |
113 | | } // namespace boost |
114 | | |
115 | | #endif |