Skip to content

Commit

Permalink
Charconv is used to serialize doubles
Browse files Browse the repository at this point in the history
  • Loading branch information
grisumbras committed Mar 18, 2024
1 parent 41e455b commit 7493c7f
Show file tree
Hide file tree
Showing 15 changed files with 53 additions and 2,358 deletions.
77 changes: 51 additions & 26 deletions include/boost/json/detail/impl/format.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
#define BOOST_JSON_DETAIL_IMPL_FORMAT_IPP

#include <boost/charconv/to_chars.hpp>
#include <boost/json/detail/ryu/detail/common.hpp>
#include <cmath>
#include <cstring>
#include <limits>

namespace boost {
namespace json {
Expand Down Expand Up @@ -115,35 +116,59 @@ unsigned
format_double(
char* dest, double d, bool allow_infinity_and_nan) noexcept
{
namespace ryud = ryu::detail;
// Copyright 2018 Ulf Adams
//
// Decode bits into sign, mantissa, and exponent.
std::uint64_t const bits = ryud::double_to_bits(d);
const bool ieeeSign = ((bits >> (ryud::DOUBLE_MANTISSA_BITS + ryud::DOUBLE_EXPONENT_BITS)) & 1) != 0;
const std::uint64_t ieeeMantissa = bits & ((1ull << ryud::DOUBLE_MANTISSA_BITS) - 1);
const std::uint32_t ieeeExponent = (std::uint32_t)((bits >> ryud::DOUBLE_MANTISSA_BITS) & ((1u << ryud::DOUBLE_EXPONENT_BITS) - 1));
// Case distinction; exit early for the easy cases.
if(BOOST_JSON_UNLIKELY(
ieeeExponent == ((1u << ryud::DOUBLE_EXPONENT_BITS) - 1u) ||
(ieeeExponent == 0
&& ieeeMantissa == 0) ))
charconv::to_chars_result result;

using Limits = std::numeric_limits<double>;

if(BOOST_JSON_UNLIKELY( std::isnan(d) ))
{
// We changed how special numbers are output by default
if (allow_infinity_and_nan)
return ryud::copy_special_str(
dest, ieeeSign, ieeeExponent != 0, ieeeMantissa != 0);
if( allow_infinity_and_nan )
{
std::memcpy(dest, "NaN", 3);
result.ptr = dest + 3;
}
else
return ryud::copy_special_str_conforming(
dest, ieeeSign, ieeeExponent != 0, ieeeMantissa != 0);

{
std::memcpy(dest, "null", 4);
result.ptr = dest + 4;
}
}
else if(BOOST_JSON_UNLIKELY( d == Limits::infinity() ))
{
if( allow_infinity_and_nan )
{
std::memcpy(dest, "Infinity", 8);
result.ptr = dest + 8;
}
else
{
std::memcpy(dest, "1e99999", 7);
result.ptr = dest + 7;
}
}
else if(BOOST_JSON_UNLIKELY( d == -Limits::infinity() ))
{
if( allow_infinity_and_nan )
{
std::memcpy(dest, "-Infinity", 9);
result.ptr = dest + 9;
}
else
{
std::memcpy(dest, "-1e99999", 8);
result.ptr = dest + 8;
}
}
else
{
result = charconv::to_chars(
dest,
dest + detail::max_number_chars,
d,
charconv::chars_format::scientific);
BOOST_ASSERT( result.ec == std::errc() );
}

auto const result = charconv::to_chars(
dest,
dest + detail::max_number_chars,
d,
charconv::chars_format::scientific);
return result.ptr - dest;
}

Expand Down
144 changes: 0 additions & 144 deletions include/boost/json/detail/ryu/detail/common.hpp

This file was deleted.

Loading

0 comments on commit 7493c7f

Please sign in to comment.