@@ -17886,10 +17886,11 @@ notation. Otherwise it will be printed in exponential notation.
17886
17886
JSON_HEDLEY_NON_NULL(1)
17887
17887
JSON_HEDLEY_RETURNS_NON_NULL
17888
17888
inline char* format_buffer(char* buf, int len, int decimal_exponent,
17889
- int min_exp, int max_exp)
17889
+ int min_exp, int max_exp, size_t precision )
17890
17890
{
17891
17891
JSON_ASSERT(min_exp < 0);
17892
17892
JSON_ASSERT(max_exp > 0);
17893
+ precision = std::min<size_t>(precision, 1000);
17893
17894
17894
17895
const int k = len;
17895
17896
const int n = len + decimal_exponent;
@@ -17919,7 +17920,7 @@ inline char* format_buffer(char* buf, int len, int decimal_exponent,
17919
17920
17920
17921
std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
17921
17922
buf[n] = '.';
17922
- return buf + (static_cast<size_t>(k) + 1U);
17923
+ return buf + (std::min(n + precision, static_cast<size_t>(k) ) + 1U);
17923
17924
}
17924
17925
17925
17926
if (min_exp < n && n <= 0)
@@ -17931,7 +17932,7 @@ inline char* format_buffer(char* buf, int len, int decimal_exponent,
17931
17932
buf[0] = '0';
17932
17933
buf[1] = '.';
17933
17934
std::memset(buf + 2, '0', static_cast<size_t>(-n));
17934
- return buf + ( 2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
17935
+ return buf + std::min(precision + 2, ( 2U + static_cast<size_t>(-n) + static_cast<size_t>(k) ));
17935
17936
}
17936
17937
17937
17938
if (k == 1)
@@ -17948,7 +17949,7 @@ inline char* format_buffer(char* buf, int len, int decimal_exponent,
17948
17949
17949
17950
std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
17950
17951
buf[1] = '.';
17951
- buf += 1 + static_cast<size_t>(k);
17952
+ buf += 1 + std::min(precision, static_cast<size_t>(k) );
17952
17953
}
17953
17954
17954
17955
*buf++ = 'e';
@@ -17970,7 +17971,7 @@ format. Returns an iterator pointing past-the-end of the decimal representation.
17970
17971
template<typename FloatType>
17971
17972
JSON_HEDLEY_NON_NULL(1, 2)
17972
17973
JSON_HEDLEY_RETURNS_NON_NULL
17973
- char* to_chars(char* first, const char* last, FloatType value)
17974
+ char* to_chars(char* first, const char* last, FloatType value, size_t precision = std::numeric_limits<FloatType>::max_digits10 )
17974
17975
{
17975
17976
static_cast<void>(last); // maybe unused - fix warning
17976
17977
JSON_ASSERT(std::isfinite(value));
@@ -18019,7 +18020,7 @@ char* to_chars(char* first, const char* last, FloatType value)
18019
18020
JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
18020
18021
JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
18021
18022
18022
- return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
18023
+ return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp, precision );
18023
18024
}
18024
18025
18025
18026
} // namespace detail
@@ -18073,13 +18074,14 @@ class serializer
18073
18074
@param[in] ichar indentation character to use
18074
18075
@param[in] error_handler_ how to react on decoding errors
18075
18076
*/
18076
- serializer(output_adapter_t<char> s, const char ichar,
18077
+ serializer(output_adapter_t<char> s, const char ichar, size_t precision = 1000,
18077
18078
error_handler_t error_handler_ = error_handler_t::strict)
18078
18079
: o(std::move(s))
18079
18080
, loc(std::localeconv())
18080
18081
, thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
18081
18082
, decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
18082
18083
, indent_char(ichar)
18084
+ , precision(precision)
18083
18085
, indent_string(512, indent_char)
18084
18086
, error_handler(error_handler_)
18085
18087
{}
@@ -18829,7 +18831,7 @@ class serializer
18829
18831
void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
18830
18832
{
18831
18833
auto* begin = number_buffer.data();
18832
- auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
18834
+ auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x, precision );
18833
18835
18834
18836
o->write_characters(begin, static_cast<size_t>(end - begin));
18835
18837
}
@@ -18841,6 +18843,8 @@ class serializer
18841
18843
18842
18844
// the actual conversion
18843
18845
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18846
+ char format[100];
18847
+ snprintf(format, 100, "%%.%dg", precision);
18844
18848
std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
18845
18849
18846
18850
// negative value indicates an error
@@ -18986,6 +18990,8 @@ class serializer
18986
18990
18987
18991
/// the indentation character
18988
18992
const char indent_char;
18993
+ /// precision for floating point output
18994
+ size_t precision;
18989
18995
/// the indentation string
18990
18996
string_t indent_string;
18991
18997
@@ -20575,10 +20581,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
20575
20581
string_t dump(const int indent = -1,
20576
20582
const char indent_char = ' ',
20577
20583
const bool ensure_ascii = false,
20578
- const error_handler_t error_handler = error_handler_t::strict) const
20584
+ const error_handler_t error_handler = error_handler_t::strict,
20585
+ const size_t precision = std::numeric_limits<size_t>::max()) const
20579
20586
{
20580
20587
string_t result;
20581
- serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
20588
+ serializer s(detail::output_adapter<char, string_t>(result), indent_char, precision, error_handler);
20582
20589
20583
20590
if (indent >= 0)
20584
20591
{
@@ -23278,15 +23285,17 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
23278
23285
friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23279
23286
{
23280
23287
// read width member and use it as indentation parameter if nonzero
23281
- const bool pretty_print = o.width() > 0;
23282
- const auto indentation = pretty_print ? o.width() : 0;
23288
+ const auto width = o.width();
23289
+ const bool pretty_print = width > 0;
23290
+ const auto indentation = pretty_print ? width : 0;
23283
23291
23284
23292
// reset width to 0 for subsequent calls to this stream
23285
23293
o.width(0);
23286
23294
23287
23295
// do the actual serialization
23288
- serializer s(detail::output_adapter<char>(o), o.fill());
23296
+ serializer s(detail::output_adapter<char>(o), o.fill(), o.precision() );
23289
23297
s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23298
+
23290
23299
return o;
23291
23300
}
23292
23301
0 commit comments