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-02-13 18:42:28 Functions: 100.0 % 6 6

            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         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