LCOV - code coverage report
Current view: top level - json/detail/ryu/detail - common.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 38 38
Test Date: 2026-07-09 14:05:02 Functions: 100.0 % 6 6

           TLA  Line data    Source code
       1                 : // Copyright 2018 Ulf Adams
       2                 : //
       3                 : // The contents of this file may be used under the terms of the Apache License,
       4                 : // Version 2.0.
       5                 : //
       6                 : //    (See accompanying file LICENSE-Apache or copy at
       7                 : //     http://www.apache.org/licenses/LICENSE-2.0)
       8                 : //
       9                 : // Alternatively, the contents of this file may be used under the terms of
      10                 : // the Boost Software License, Version 1.0.
      11                 : //    (See accompanying file LICENSE-Boost or copy at
      12                 : //     https://www.boost.org/LICENSE_1_0.txt)
      13                 : //
      14                 : // Unless required by applicable law or agreed to in writing, this software
      15                 : // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      16                 : // KIND, either express or implied.
      17                 : 
      18                 : /*
      19                 :     This is a derivative work
      20                 : */
      21                 : 
      22                 : #ifndef BOOST_JSON_DETAIL_RYU_DETAIL_COMMON_HPP
      23                 : #define BOOST_JSON_DETAIL_RYU_DETAIL_COMMON_HPP
      24                 : 
      25                 : #include <boost/json/detail/config.hpp>
      26                 : #include <string.h>
      27                 : 
      28                 : namespace boost {
      29                 : namespace json {
      30                 : namespace detail {
      31                 : 
      32                 : namespace ryu {
      33                 : namespace detail {
      34                 : 
      35                 : constexpr int DOUBLE_MANTISSA_BITS = 52;
      36                 : constexpr int DOUBLE_EXPONENT_BITS = 11;
      37                 : constexpr int DOUBLE_BIAS = 1023;
      38                 : 
      39                 : #if defined(_M_IX86) || defined(_M_ARM)
      40                 : #define BOOST_JSON_RYU_32_BIT_PLATFORM
      41                 : #endif
      42                 : 
      43                 : inline uint32_t decimalLength9(const uint32_t v) {
      44                 :   // Function precondition: v is not a 10-digit number.
      45                 :   // (f2s: 9 digits are sufficient for round-tripping.)
      46                 :   // (d2fixed: We print 9-digit blocks.)
      47                 :   BOOST_ASSERT(v < 1000000000);
      48                 :   if (v >= 100000000) { return 9; }
      49                 :   if (v >= 10000000) { return 8; }
      50                 :   if (v >= 1000000) { return 7; }
      51                 :   if (v >= 100000) { return 6; }
      52                 :   if (v >= 10000) { return 5; }
      53                 :   if (v >= 1000) { return 4; }
      54                 :   if (v >= 100) { return 3; }
      55                 :   if (v >= 10) { return 2; }
      56                 :   return 1;
      57                 : }
      58                 : 
      59                 : // Returns e == 0 ? 1 : ceil(log_2(5^e)).
      60 HIT        2634 : inline int32_t pow5bits(const int32_t e) {
      61                 :   // This approximation works up to the point that the multiplication overflows at e = 3529.
      62                 :   // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater
      63                 :   // than 2^9297.
      64            2634 :   BOOST_ASSERT(e >= 0);
      65            2634 :   BOOST_ASSERT(e <= 3528);
      66            2634 :   return (int32_t) (((((uint32_t) e) * 1217359) >> 19) + 1);
      67                 : }
      68                 : 
      69                 : // Returns floor(log_10(2^e)).
      70             128 : inline uint32_t log10Pow2(const int32_t e) {
      71                 :   // The first value this approximation fails for is 2^1651 which is just greater than 10^297.
      72             128 :   BOOST_ASSERT(e >= 0);
      73             128 :   BOOST_ASSERT(e <= 1650);
      74             128 :   return (((uint32_t) e) * 78913) >> 18;
      75                 : }
      76                 : 
      77                 : // Returns floor(log_10(5^e)).
      78             134 : inline uint32_t log10Pow5(const int32_t e) {
      79                 :   // The first value this approximation fails for is 5^2621 which is just greater than 10^1832.
      80             134 :   BOOST_ASSERT(e >= 0);
      81             134 :   BOOST_ASSERT(e <= 2620);
      82             134 :   return (((uint32_t) e) * 732923) >> 20;
      83                 : }
      84                 : 
      85              11 : inline int copy_special_str(char * const result, const bool sign, const bool exponent, const bool mantissa) {
      86              11 :   if (mantissa) {
      87               3 :     memcpy(result, "NaN", 3);
      88               3 :     return 3;
      89                 :   }
      90               8 :   if (sign) {
      91               4 :     result[0] = '-';
      92                 :   }
      93               8 :   if (exponent) {
      94               6 :     memcpy(result + sign, "Infinity", 8);
      95               6 :     return sign + 8;
      96                 :   }
      97               2 :   memcpy(result + sign, "0E0", 3);
      98               2 :   return sign + 3;
      99                 : }
     100                 : 
     101                 : inline
     102                 : int
     103              60 : copy_special_str_conforming(
     104                 :     char* const result, bool sign, bool exponent, bool mantissa)
     105                 : {
     106              60 :   if (mantissa)
     107                 :   {
     108               3 :     memcpy(result, "null", 4);
     109               3 :     return 4;
     110                 :   }
     111                 : 
     112              57 :   if (sign)
     113              20 :     result[0] = '-';
     114                 : 
     115              57 :   if (exponent)
     116                 :   {
     117               6 :     memcpy(result + sign, "1e99999", 7);
     118               6 :     return sign + 7;
     119                 :   }
     120                 : 
     121              51 :   memcpy(result + sign, "0E0", 3);
     122              51 :   return sign + 3;
     123                 : }
     124                 : 
     125                 : inline uint32_t float_to_bits(const float f) {
     126                 :   uint32_t bits = 0;
     127                 :   memcpy(&bits, &f, sizeof(float));
     128                 :   return bits;
     129                 : }
     130                 : 
     131             609 : inline uint64_t double_to_bits(const double d) {
     132             609 :   uint64_t bits = 0;
     133             609 :   memcpy(&bits, &d, sizeof(double));
     134             609 :   return bits;
     135                 : }
     136                 : 
     137                 : } // detail
     138                 : } // ryu
     139                 : 
     140                 : } // detail
     141                 : } // namespace json
     142                 : } // namespace boost
     143                 : 
     144                 : #endif
        

Generated by: LCOV version 2.3