- Mark the parameters of the new out-of-line throw helpers in json.hpp as
used, as JSON_THROW drops its argument with JSON_NOEXCEPTION (clang
-Wunused-parameter).
- all_children_leaves() iterates with begin()/end() via std::all_of: a
custom array_t such as the one in the custom_array_type example has no
rbegin() (examples check, clang-tidy readability-use-anyofallof).
- The rvalue to_json overloads (#5837) copy the elements of containers
with const elements such as std::set instead of moving them: GCC 4.9's
std::move_iterator cannot bind them. Object types are ruled out before
std::ranges::view is checked, which needs an incomplete ordered_json
for its object_t (GCC 11, C++20, unit-regression3 #3312).
- NOLINT the rvalue to_json parameters that are deliberately not
forwarded, and fix the other clang-tidy findings (modernize-use-auto in
zmij.hpp, readability-math-missing-parentheses in json_pointer.hpp).
- cpplint: NOLINT(readability/braces) on the new scalar fast-path macro
like on JSON_IMPLEMENT_OPERATOR, and include <map> in json.hpp.
- Tests: drop a useless cast (GCC -Wuseless-cast) and a signed/unsigned
comparison (MSVC C4018), wrap a vector<json> comparison in parentheses
so doctest does not try to print it (ambiguous operator<< on MSVC), and
also strip JSON_DIAGNOSTIC_POSITIONS' "(bytes x-y) " from the patch
messages in unit-throw_messages.
- Windows clang (MinGW): link with LLD. unit-msgpack.cpp (C++11) and
unit-regression2.cpp (C++20) have more than 32767 sections again
(33363 and 33197), which GNU ld cannot link; LLD links them.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
MSVC 2015 warns C4554 on the shifts with casts in the fractional part
of zmij::to_shortest despite the parentheses; with /WX every target
fails to build. Name the shift amounts as constants instead.
The shortest-digits test built the candidates with one digit fewer via
a stream with std::setprecision(digits.size() - 2); the standard library
of MSVC 2017 ignores a precision of 0, so for two-digit values the
"shorter" candidates were the value itself. Truncate the digits
instead: the value lies within half a unit of the last digit, so the
truncated digits and their successor are the closest candidates.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Write doubles with the shortest digits (Żmij), digits in registers
Write doubles with the conversion of Zmij by Victor Zverovich (MIT),
ported to C++11 (detail/conversions/zmij.hpp). It finds the
shortest decimal that reads back as the same double, and the
closest one if there are several. Grisu2, used until now, is fast
but not always shortest: it sometimes writes a 17th digit where 16
suffice, or a last digit that is not the closest. The layout is
unchanged (1.5, 100.0, 1e+100, -0.0); float keeps Grisu2.
Digits are converted eight at a time with the BCD conversion of
Xiang JunBo, as in Zmij, and written with one byte swap per eight
digits and fixed-size moves instead of per-digit loops. Leading and
trailing zeros are counted from those bytes. to_chars() uses a
local buffer when the caller's is shorter than the 41 bytes this
may write. The powers of ten come from the number-parsing table,
adjusted where it holds values rounded up, and extended with Zmij's
compressed tables beyond 10^308.
write_shortest() converts its 16 digits in one vector register
(SSE2 on x86-64, NEON on 64-bit Arm, both baseline) and inserts the
decimal point inside the register, avoiding a store-forwarding
stall that cost about 25% of the time to write a double. dump()
writes floats and integers straight into the serializer's write
buffer instead of copying them from a member buffer, and small
integers eight digits at a time. read_eight_bytes() and
parse_eight_digits() are marked always-inline, which GCC had been
calling out of line in the number-parsing loops.
Of one million random doubles, about 0.14% are now written with
different digits, always to a value that still reads back as the
same double.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix CI findings in the Zmij writer and its tests
- bit_ops.hpp: include macro_scope.hpp (JSON_HEDLEY_ALWAYS_INLINE); fixes IWYU
- to_chars.hpp: C4100 for the unused parameter in release builds, clang-tidy
sign comparison, cpplint runtime/int, GCC -Wstrict-overflow (unsigned abs)
- unit-to_chars.cpp: parse with the library instead of strtod (MinGW's strtod
rounds some 16/17 digit inputs wrongly); no floating-point std::to_chars
with icpc
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Select the Zmij conversion by a trait, not by the double overload
The non-template overloads for double asserted binary64 doubles wherever json.hpp was included, so the library no longer compiled where double is not IEEE 754 binary64 (AVR, -fshort-double). A trait now picks Zmij for any binary64 type, including a long double of that format (MSVC, Apple Arm), and Grisu2 for the others. Remove the unused write_short_decimal, powers_of_ten_16, zmij::decimal, zmij::to_decimal, and shortest_digits(double).
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Credit Zmij's authors in to_chars.hpp, the README, and the license page
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Silence MSVC C4127 for a platform-constant check in the to_chars test
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Regenerate the amalgamated headers
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>