LCOV - code coverage report
Current view: top level - json/detail/impl - format.ipp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 40 40
Test Date: 2025-12-23 17:20:51 Functions: 100.0 % 7 7

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3              : // Copyright (c) 2020 Peter Dimov (pdimov at gmail dot com),
       4              : //
       5              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7              : //
       8              : // Official repository: https://github.com/boostorg/json
       9              : //
      10              : 
      11              : #ifndef BOOST_JSON_DETAIL_IMPL_FORMAT_IPP
      12              : #define BOOST_JSON_DETAIL_IMPL_FORMAT_IPP
      13              : 
      14              : #include <boost/json/detail/ryu/ryu.hpp>
      15              : #include <cstring>
      16              : 
      17              : namespace boost {
      18              : namespace json {
      19              : namespace detail {
      20              : 
      21              : /*  Reference work:
      22              : 
      23              :     https://www.ampl.com/netlib/fp/dtoa.c
      24              :     https://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
      25              :     https://kkimdev.github.io/posts/2018/06/15/IEEE-754-Floating-Point-Type-in-C++.html
      26              : */
      27              : 
      28         4839 : inline char const* digits_lut() noexcept
      29              : {
      30              :     return
      31              :         "00010203040506070809"
      32              :         "10111213141516171819"
      33              :         "20212223242526272829"
      34              :         "30313233343536373839"
      35              :         "40414243444546474849"
      36              :         "50515253545556575859"
      37              :         "60616263646566676869"
      38              :         "70717273747576777879"
      39              :         "80818283848586878889"
      40         4839 :         "90919293949596979899";
      41              : }
      42              : 
      43         1988 : inline void format_four_digits( char * dest, unsigned v )
      44              : {
      45         1988 :     std::memcpy( dest + 2, digits_lut() + (v % 100) * 2, 2 );
      46         1988 :     std::memcpy( dest    , digits_lut() + (v / 100) * 2, 2 );
      47         1988 : }
      48              : 
      49          863 : inline void format_two_digits( char * dest, unsigned v )
      50              : {
      51          863 :     std::memcpy( dest, digits_lut() + v * 2, 2 );
      52          863 : }
      53              : 
      54          405 : inline void format_digit( char * dest, unsigned v )
      55              : {
      56          405 :     *dest = static_cast<char>( v + '0' );
      57          405 : }
      58              : 
      59              : unsigned
      60         3614 : format_uint64(
      61              :     char* dest,
      62              :     std::uint64_t v) noexcept
      63              : {
      64         3614 :     if(v < 10)
      65              :     {
      66         2475 :         *dest = static_cast<char>( '0' + v );
      67         2475 :         return 1;
      68              :     }
      69              : 
      70              :     char buffer[ 24 ];
      71              : 
      72         1139 :     char * p = buffer + 24;
      73              : 
      74         3127 :     while( v >= 1000 )
      75              :     {
      76         1988 :         p -= 4;
      77         1988 :         format_four_digits( p, v % 10000 );
      78         1988 :         v /= 10000;
      79              :     }
      80              : 
      81         1139 :     if( v >= 10 )
      82              :     {
      83          863 :         p -= 2;
      84          863 :         format_two_digits( p, v % 100 );
      85          863 :         v /= 100;
      86              :     }
      87              : 
      88         1139 :     if( v )
      89              :     {
      90          405 :         p -= 1;
      91          405 :         format_digit( p, static_cast<unsigned>(v) );
      92              :     }
      93              : 
      94         1139 :     unsigned const n = static_cast<unsigned>( buffer + 24 - p );
      95         1139 :     std::memcpy( dest, p, n );
      96              : 
      97         1139 :     return n;
      98              : }
      99              : 
     100              : unsigned
     101         3189 : format_int64(
     102              :     char* dest, int64_t i) noexcept
     103              : {
     104         3189 :     std::uint64_t ui = static_cast<
     105              :         std::uint64_t>(i);
     106         3189 :     if(i >= 0)
     107         2747 :         return format_uint64(dest, ui);
     108          442 :     *dest++ = '-';
     109          442 :     ui = ~ui + 1;
     110          442 :     return 1 + format_uint64(dest, ui);
     111              : }
     112              : 
     113              : unsigned
     114          477 : format_double(
     115              :     char* dest, double d, bool allow_infinity_and_nan) noexcept
     116              : {
     117              :     return static_cast<int>(
     118          477 :         ryu::d2s_buffered_n(d, dest, allow_infinity_and_nan));
     119              : }
     120              : 
     121              : } // detail
     122              : } // namespace json
     123              : } // namespace boost
     124              : 
     125              : #endif
        

Generated by: LCOV version 2.1