make sure precision is reset on output streams during serialization
This commit is contained in:
parent
cb145cfe71
commit
1286d35767
3 changed files with 66 additions and 18 deletions
31
src/json.hpp
31
src/json.hpp
|
@ -2120,6 +2120,12 @@ class basic_json
|
||||||
// fix locale problems
|
// fix locale problems
|
||||||
ss.imbue(std::locale(std::locale(), new DecimalSeparator));
|
ss.imbue(std::locale(std::locale(), new DecimalSeparator));
|
||||||
|
|
||||||
|
// 6, 15 or 16 digits of precision allows round-trip IEEE 754
|
||||||
|
// string->float->string, string->double->string or string->long
|
||||||
|
// double->string; to be safe, we read this value from
|
||||||
|
// std::numeric_limits<number_float_t>::digits10
|
||||||
|
ss.precision(std::numeric_limits<double>::digits10);
|
||||||
|
|
||||||
if (indent >= 0)
|
if (indent >= 0)
|
||||||
{
|
{
|
||||||
dump(ss, true, static_cast<unsigned int>(indent));
|
dump(ss, true, static_cast<unsigned int>(indent));
|
||||||
|
@ -5693,6 +5699,10 @@ class basic_json
|
||||||
`std::setw(4)` on @a o sets the indentation level to `4` and the
|
`std::setw(4)` on @a o sets the indentation level to `4` and the
|
||||||
serialization result is the same as calling `dump(4)`.
|
serialization result is the same as calling `dump(4)`.
|
||||||
|
|
||||||
|
@note During serializaion, the locale and the precision of the output
|
||||||
|
stream @a o are changed. The original values are restored when the
|
||||||
|
function returns.
|
||||||
|
|
||||||
@param[in,out] o stream to serialize to
|
@param[in,out] o stream to serialize to
|
||||||
@param[in] j JSON value to serialize
|
@param[in] j JSON value to serialize
|
||||||
|
|
||||||
|
@ -5713,14 +5723,23 @@ class basic_json
|
||||||
|
|
||||||
// reset width to 0 for subsequent calls to this stream
|
// reset width to 0 for subsequent calls to this stream
|
||||||
o.width(0);
|
o.width(0);
|
||||||
|
|
||||||
// fix locale problems
|
// fix locale problems
|
||||||
auto old_locale = o.imbue(std::locale(std::locale(), new DecimalSeparator));
|
const auto old_locale = o.imbue(std::locale(std::locale(), new DecimalSeparator));
|
||||||
|
// set precision
|
||||||
|
|
||||||
|
// 6, 15 or 16 digits of precision allows round-trip IEEE 754
|
||||||
|
// string->float->string, string->double->string or string->long
|
||||||
|
// double->string; to be safe, we read this value from
|
||||||
|
// std::numeric_limits<number_float_t>::digits10
|
||||||
|
const auto old_preicison = o.precision(std::numeric_limits<double>::digits10);
|
||||||
|
|
||||||
// do the actual serialization
|
// do the actual serialization
|
||||||
j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
|
j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
|
||||||
|
|
||||||
// reset locale
|
// reset locale and precision
|
||||||
o.imbue(old_locale);
|
o.imbue(old_locale);
|
||||||
|
o.precision(old_preicison);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6184,13 +6203,7 @@ class basic_json
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Otherwise 6, 15 or 16 digits of precision allows
|
o << m_value.number_float;
|
||||||
// round-trip IEEE 754 string->float->string,
|
|
||||||
// string->double->string or string->long
|
|
||||||
// double->string; to be safe, we read this value from
|
|
||||||
// std::numeric_limits<number_float_t>::digits10
|
|
||||||
o << std::setprecision(std::numeric_limits<double>::digits10)
|
|
||||||
<< m_value.number_float;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2120,6 +2120,12 @@ class basic_json
|
||||||
// fix locale problems
|
// fix locale problems
|
||||||
ss.imbue(std::locale(std::locale(), new DecimalSeparator));
|
ss.imbue(std::locale(std::locale(), new DecimalSeparator));
|
||||||
|
|
||||||
|
// 6, 15 or 16 digits of precision allows round-trip IEEE 754
|
||||||
|
// string->float->string, string->double->string or string->long
|
||||||
|
// double->string; to be safe, we read this value from
|
||||||
|
// std::numeric_limits<number_float_t>::digits10
|
||||||
|
ss.precision(std::numeric_limits<double>::digits10);
|
||||||
|
|
||||||
if (indent >= 0)
|
if (indent >= 0)
|
||||||
{
|
{
|
||||||
dump(ss, true, static_cast<unsigned int>(indent));
|
dump(ss, true, static_cast<unsigned int>(indent));
|
||||||
|
@ -5693,6 +5699,10 @@ class basic_json
|
||||||
`std::setw(4)` on @a o sets the indentation level to `4` and the
|
`std::setw(4)` on @a o sets the indentation level to `4` and the
|
||||||
serialization result is the same as calling `dump(4)`.
|
serialization result is the same as calling `dump(4)`.
|
||||||
|
|
||||||
|
@note During serializaion, the locale and the precision of the output
|
||||||
|
stream @a o are changed. The original values are restored when the
|
||||||
|
function returns.
|
||||||
|
|
||||||
@param[in,out] o stream to serialize to
|
@param[in,out] o stream to serialize to
|
||||||
@param[in] j JSON value to serialize
|
@param[in] j JSON value to serialize
|
||||||
|
|
||||||
|
@ -5713,14 +5723,23 @@ class basic_json
|
||||||
|
|
||||||
// reset width to 0 for subsequent calls to this stream
|
// reset width to 0 for subsequent calls to this stream
|
||||||
o.width(0);
|
o.width(0);
|
||||||
|
|
||||||
// fix locale problems
|
// fix locale problems
|
||||||
auto old_locale = o.imbue(std::locale(std::locale(), new DecimalSeparator));
|
const auto old_locale = o.imbue(std::locale(std::locale(), new DecimalSeparator));
|
||||||
|
// set precision
|
||||||
|
|
||||||
|
// 6, 15 or 16 digits of precision allows round-trip IEEE 754
|
||||||
|
// string->float->string, string->double->string or string->long
|
||||||
|
// double->string; to be safe, we read this value from
|
||||||
|
// std::numeric_limits<number_float_t>::digits10
|
||||||
|
const auto old_preicison = o.precision(std::numeric_limits<double>::digits10);
|
||||||
|
|
||||||
// do the actual serialization
|
// do the actual serialization
|
||||||
j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
|
j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
|
||||||
|
|
||||||
// reset locale
|
// reset locale and precision
|
||||||
o.imbue(old_locale);
|
o.imbue(old_locale);
|
||||||
|
o.precision(old_preicison);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6184,13 +6203,7 @@ class basic_json
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Otherwise 6, 15 or 16 digits of precision allows
|
o << m_value.number_float;
|
||||||
// round-trip IEEE 754 string->float->string,
|
|
||||||
// string->double->string or string->long
|
|
||||||
// double->string; to be safe, we read this value from
|
|
||||||
// std::numeric_limits<number_float_t>::digits10
|
|
||||||
o << std::setprecision(std::numeric_limits<double>::digits10)
|
|
||||||
<< m_value.number_float;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1685,6 +1685,28 @@ TEST_CASE("object inspection")
|
||||||
json j_discarded(json::value_t::discarded);
|
json j_discarded(json::value_t::discarded);
|
||||||
CHECK(j_discarded.dump() == "<discarded>");
|
CHECK(j_discarded.dump() == "<discarded>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("check that precision is reset after serialization")
|
||||||
|
{
|
||||||
|
// create stringstream and set precision
|
||||||
|
std::stringstream ss;
|
||||||
|
ss.precision(3);
|
||||||
|
ss << 3.141592653589793 << std::fixed;
|
||||||
|
CHECK(ss.str() == "3.14");
|
||||||
|
|
||||||
|
// reset stringstream
|
||||||
|
ss.str(std::string());
|
||||||
|
|
||||||
|
// use stringstream for JSON serialization
|
||||||
|
json j_number = 3.141592653589793;
|
||||||
|
ss << j_number;
|
||||||
|
|
||||||
|
// check that precision has been overridden during serialization
|
||||||
|
CHECK(ss.str() == "3.141592653589793");
|
||||||
|
|
||||||
|
// check that precision has been restored
|
||||||
|
CHECK(ss.precision() == 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("return the type of the object (explicit)")
|
SECTION("return the type of the object (explicit)")
|
||||||
|
|
Loading…
Reference in a new issue