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