LCOV - code coverage report
Current view: top level - json/detail - digest.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 27 27
Test Date: 2025-12-23 16:57:37 Functions: 100.0 % 2 2

            Line data    Source code
       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        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        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
        

Generated by: LCOV version 2.1