@@ -17886,10 +17886,11 @@ notation. Otherwise it will be printed in exponential notation.
1788617886JSON_HEDLEY_NON_NULL(1)
1788717887JSON_HEDLEY_RETURNS_NON_NULL
1788817888inline 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 )
1789017890{
1789117891 JSON_ASSERT(min_exp < 0);
1789217892 JSON_ASSERT(max_exp > 0);
17893+ precision = std::min<size_t>(precision, 1000);
1789317894
1789417895 const int k = len;
1789517896 const int n = len + decimal_exponent;
@@ -17919,7 +17920,7 @@ inline char* format_buffer(char* buf, int len, int decimal_exponent,
1791917920
1792017921 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
1792117922 buf[n] = '.';
17922- return buf + (static_cast<size_t>(k) + 1U);
17923+ return buf + (std::min(n + precision, static_cast<size_t>(k) ) + 1U);
1792317924 }
1792417925
1792517926 if (min_exp < n && n <= 0)
@@ -17931,7 +17932,7 @@ inline char* format_buffer(char* buf, int len, int decimal_exponent,
1793117932 buf[0] = '0';
1793217933 buf[1] = '.';
1793317934 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) ));
1793517936 }
1793617937
1793717938 if (k == 1)
@@ -17948,7 +17949,7 @@ inline char* format_buffer(char* buf, int len, int decimal_exponent,
1794817949
1794917950 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
1795017951 buf[1] = '.';
17951- buf += 1 + static_cast<size_t>(k);
17952+ buf += 1 + std::min(precision, static_cast<size_t>(k) );
1795217953 }
1795317954
1795417955 *buf++ = 'e';
@@ -17970,7 +17971,7 @@ format. Returns an iterator pointing past-the-end of the decimal representation.
1797017971template<typename FloatType>
1797117972JSON_HEDLEY_NON_NULL(1, 2)
1797217973JSON_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 )
1797417975{
1797517976 static_cast<void>(last); // maybe unused - fix warning
1797617977 JSON_ASSERT(std::isfinite(value));
@@ -18019,7 +18020,7 @@ char* to_chars(char* first, const char* last, FloatType value)
1801918020 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
1802018021 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
1802118022
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 );
1802318024}
1802418025
1802518026} // namespace detail
@@ -18073,13 +18074,14 @@ class serializer
1807318074 @param[in] ichar indentation character to use
1807418075 @param[in] error_handler_ how to react on decoding errors
1807518076 */
18076- serializer(output_adapter_t<char> s, const char ichar,
18077+ serializer(output_adapter_t<char> s, const char ichar, size_t precision = 1000,
1807718078 error_handler_t error_handler_ = error_handler_t::strict)
1807818079 : o(std::move(s))
1807918080 , loc(std::localeconv())
1808018081 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
1808118082 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
1808218083 , indent_char(ichar)
18084+ , precision(precision)
1808318085 , indent_string(512, indent_char)
1808418086 , error_handler(error_handler_)
1808518087 {}
@@ -18829,7 +18831,7 @@ class serializer
1882918831 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
1883018832 {
1883118833 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 );
1883318835
1883418836 o->write_characters(begin, static_cast<size_t>(end - begin));
1883518837 }
@@ -18841,6 +18843,8 @@ class serializer
1884118843
1884218844 // the actual conversion
1884318845 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18846+ char format[100];
18847+ snprintf(format, 100, "%%.%dg", precision);
1884418848 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
1884518849
1884618850 // negative value indicates an error
@@ -18986,6 +18990,8 @@ class serializer
1898618990
1898718991 /// the indentation character
1898818992 const char indent_char;
18993+ /// precision for floating point output
18994+ size_t precision;
1898918995 /// the indentation string
1899018996 string_t indent_string;
1899118997
@@ -20575,10 +20581,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2057520581 string_t dump(const int indent = -1,
2057620582 const char indent_char = ' ',
2057720583 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
2057920586 {
2058020587 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);
2058220589
2058320590 if (indent >= 0)
2058420591 {
@@ -23278,15 +23285,17 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2327823285 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
2327923286 {
2328023287 // 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;
2328323291
2328423292 // reset width to 0 for subsequent calls to this stream
2328523293 o.width(0);
2328623294
2328723295 // 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() );
2328923297 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23298+
2329023299 return o;
2329123300 }
2329223301
0 commit comments