GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: detail/digest.hpp
Date: 2025-12-23 16:57:39
Exec Total Coverage
Lines: 27 27 100.0%
Functions: 1 1 100.0%
Branches: 5 10 50.0%

Line Branch Exec 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 11262 digest(ForwardIterator b, ForwardIterator e, std::size_t salt) noexcept
26 {
27 11262 std::size_t const len = std::distance(b, e);
28
29 #if BOOST_JSON_ARCH == 64
30
31 using state_type = std::uint64_t;
32 11262 state_type const m = 0xc6a4a7935bd1e995ULL;
33 11262 int const r = 47;
34 11262 state_type hash = salt ^ (len * m);
35
36 11262 constexpr std::size_t N = sizeof(state_type);
37 11262 e = std::next( b, len & ~std::size_t(N-1) );
38
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2241 times.
11292 for( ; b != e; std::advance(b, N) )
39 {
40 state_type num;
41 #ifdef _MSC_VER
42 # pragma warning(push)
43 # pragma warning(disable: 4996)
44 #endif
45 30 std::copy_n( b, N, reinterpret_cast<unsigned char*>(&num) );
46 #ifdef _MSC_VER
47 # pragma warning(pop)
48 #endif
49
50 30 num *= m;
51 30 num ^= num >> r;
52 30 num *= m;
53 30 hash ^= num;
54 30 hash *= m;
55 }
56
57
4/8
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 633 times.
✓ Branch 6 taken 1604 times.
✗ Branch 7 not taken.
11262 switch( len & (N - 1) )
58 {
59 12 case 7: hash ^= state_type( *std::next(b, 6) ) << 48; // fall through
60 24 case 6: hash ^= state_type( *std::next(b, 5) ) << 40; // fall through
61 40 case 5: hash ^= state_type( *std::next(b, 4) ) << 32; // fall through
62 70 case 4: hash ^= state_type( *std::next(b, 3) ) << 24; // fall through
63 5502 case 3: hash ^= state_type( *std::next(b, 2) ) << 16; // fall through
64 12624 case 2: hash ^= state_type( *std::next(b, 1) ) << 8; // fall through
65 11272 case 1: hash ^= state_type( *std::next(b, 0) );
66 11256 hash *= m;
67 };
68
69 11262 hash ^= hash >> r;
70 11262 hash *= m;
71 11262 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 11262 return hash;
109 }
110
111 } // detail
112 } // namespace json
113 } // namespace boost
114
115 #endif
116