- If an overflow occurs during parsing a number from a JSON text, an
exception (std::out_of_range for the moment, to be replaced by a
user-defined exception #244) is thrown so that the overflow is detected
early and roundtripping is guaranteed.
- NaN and INF floating-point values can be stored in a JSON value and
are not replaced by null. That is, the basic_json class behaves like
double in this regard (no exception occurs). However, NaN and INF are
serialized to “null”.
- Adjusted test cases appropriately.
To avoid the error described in #497, I added a function
msgpack_expect_string that is executed every time a string is expected
during the parsing of a map. In case the current byte does not belong
to a MsgPack string, an exception is thrown.
This test case relied on logics that have been replaced by CMake with
#461. This change enables compilation and execution of the test suite
without exceptions by adding an after_success task.
I used __EXCEPTIONS to detect whether exceptions are supported.
Apparently, this is a macro that is only used by libstdc++
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64276). It’s much cleaner
to use __cpp_exceptions as it is in the standard since C++98.
Note that compiling the unit-tests with “-fno-exceptions” still does
not work, because Catch uses throw internally. However, the library’s
exceptions can be switched off by defining JSON_NOEXCEPTION.
The original test case relied on an invalidated iterator. This error
did not occur before, but only with GCC with -D_GLIBCXX_DEBUG. This
commit fixes the test case. The library is unaffected by this change.
The constructor basic_json(std::istream&, const parser_callback_t) has
been deprecated since version 2.0.0. This commit removes it together
with its code example, deprecation macro, and test cases. The code now
also compiles with -W-deprecated-declarations.
The library does not preserve the insertion order of object keys. There
are frequent requests to change the library in this aspect. The README
and the contribution guidelines now contain links to containers that
can be used to replace std::map to preserve the insertion order.
Moved all dump()-related functions into a class "serializer". This fix includes a lot of performance improvements yielding a 7% speedup for serialization. Details on the individual steps can be found in the commit messages.
Individual benchmark numbers:
before:
dump jeopardy.json 5 374555228 ns/op
dump jeopardy.json with indent 5 430953700 ns/op
dump numbers/floats.json 5 622938509 ns/op
dump numbers/signed_ints.json 20 82177979 ns/op
after:
dump jeopardy.json 5 335449757 ns/op -11%
dump jeopardy.json with indent 5 375467773 ns/op -13%
dump numbers/floats.json 5 584611852 ns/op -7%
dump numbers/signed_ints.json 20 68289574 ns/op -17%
- Added comments for the serializer class.
- Added test case for resizing of the indentation string.
- Using std::none_of to check if “.0” needs to be added to
floating-point number.
A lot of small changes to avoid memory allocations:
- The locale is only queried once rather than with every number
serialization.
- The indentation string is recycled between different calls.
- The string escape function avoids a copy if no escaping is necessary.
- The string escape and the space function use a complete switch case
instead of cascaded ifs.
Cachegrind measures some 15% performance improvement.
Treated the size of the range as the number of thousand separators.
This logical error yielded a negative value for written_bytes and
eventually an infinite loop, as written_bytes was converted to an
unsigned value.
The class is currently just a wrapper for an std::ostream and collects
all functions related to serialization. The next step should be
recycling of variables to avoid repetitive initialization for each
recursive dump call.
numtostr now directly writes to a stream. Return value of snprintf is
reused to avoid finding end of string. Cachegrind suggests a 1%
performance increase.
All ‘<<‘ calls have been replaced by write()/put() calls. The
indentation strings needs not to be resized. Cachegrind measures 1%
performance improvement.
Indentation string is recycled to avoid allocations. Comma-separation
in objects does not need an if any more. Cachegrind measures 1%
performance improvement.
Added separate code paths for normal output and pritty-printed output.
This allowed to remove most of the ifs along the way. Benchmarks and
cachegrind suggest a 10% performance improvement.