Coverage Report

Created: 2026-03-09 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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