Compare commits

..
11 Commits
Author SHA1 Message Date
Niels Lohmann af711143a0 Use data() instead of c_str() in the multi-byte decimal point path
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-13 22:22:20 +02:00
Niels Lohmann a9b0e6b843 Address review: std::any_of in has_nonzero_digit, comment punctuation
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-13 22:22:20 +02:00
Niels Lohmann 4a28e684ea Drop the position updates in the bulk \u path, which #5809 made unused
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-13 22:22:20 +02:00
Niels Lohmann b0053eec5a Regenerate the amalgamated headers
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-13 22:22:20 +02:00
Niels Lohmann 7f3063b974 Mark the unsigned long of the MSVC bit scans for cpplint
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-13 22:22:20 +02:00
Niels Lohmann 92e8448c52 Fix clang-tidy 22 findings in unit-class_lexer.cpp
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-13 22:22:20 +02:00
Niels Lohmann aab407de27 Reword float conversion notes for the string type and number_float_t docs
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-13 22:22:20 +02:00
Niels Lohmann 802a59a14b Load string scan words with memcpy and use MSVC bit-scan intrinsics
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-13 22:22:20 +02:00
Niels Lohmann 7b6a9e8e3a Fix CI warnings in own float parser
- pow5_table.hpp: pow5_128_largest_power was unused in this branch's
  own code (GCC -Werror=unused-const-variable); tie it to the table
  size with a static_assert instead of removing it, since a later
  branch in the stack (json-view/23-zmij) uses it.
- number_parse.hpp: rename the local variable `copy` to `buffer` to
  satisfy cpplint's build/include_what_you_use check.
- unit-class_lexer.cpp: extend the NOLINT list on the seeded mt19937
  with bugprone-random-generator-seed, and parenthesize
  `8 * sizeof(Bits) - 1` for clang-tidy.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-13 22:22:20 +02:00
Niels Lohmann b5aa90a301 Speed up the lexer: own float parser, string scan, and \u table
Give the library its own correctly rounded float converter for
binary32 and binary64 (IEEE 754), and speed up the lexer's string
and escape scanning.

The converter splits a number token into sign, significand, and
decimal exponent, then tries Clinger's fast path, then a templated
Eisel-Lemire step, and falls back to an exact big-integer digit
comparison for tokens with more than 19 significant digits whose two
candidate values round differently. This replaces std::from_chars
and strtod/strtof for both formats, so parsed values no longer
depend on the C/C++ library or the current locale. The strtold
fallback kept for other long double formats (x87, binary128) now
also copies a multi-byte decimal point correctly, fixing #5660.
eisel_lemire() and decimal_to_float() are always inlined so callers
keep the whole conversion in their hot loop.

The string-scanning kernels in string_scan.hpp find a stop byte with
the trailing-zero count of the SWAR mask instead of a byte loop, and
scalar_string_bulk_run() validates a run of multi-byte UTF-8
sequences one after another instead of re-searching after each one.

get_codepoint() decodes a contiguous \uXXXX escape with one table
lookup per byte instead of four range-checked get() calls; the
streaming path and all error positions are unchanged.

Adds 508 generated hard float-parsing cases with expected binary32
and binary64 bits, and kernel-comparison tests for the string scans
and the escape table against byte-by-byte references.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-13 22:22:20 +02:00
Niels Lohmann 7461a199b5 Drop the class wrapper from the C++20 comparison operator signatures in the docs (#5814)
* Drop the class wrapper from the C++20 comparison operator signatures in the docs

The signature boxes of operator<=> and the C++20 half of operator== wrapped
the member declarations in an incomplete "class basic_json { ... };". The
trailing const already marks them as members, and no other page uses such a
wrapper.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Drop the class wrapper from the json_pointer comparison signatures too

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-13 20:06:14 +02:00
6 changed files with 16 additions and 24 deletions

No files matched your search

@@ -11,12 +11,10 @@ template<typename ScalarType>
bool operator==(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)
// since C++20
class basic_json {
bool operator==(const_reference rhs) const noexcept; // (1)
bool operator==(const_reference rhs) const noexcept; // (1)
template<typename ScalarType>
bool operator==(ScalarType rhs) const noexcept(/* see below */); // (2)
};
template<typename ScalarType>
bool operator==(ScalarType rhs) const noexcept(/* see below */); // (2)
```
1. Compares two JSON values for equality according to the following rules:
@@ -2,12 +2,10 @@
```cpp
// since C++20
class basic_json {
std::partial_ordering operator<=>(const_reference rhs) const noexcept; // (1)
std::partial_ordering operator<=>(const_reference rhs) const noexcept; // (1)
template<typename ScalarType>
std::partial_ordering operator<=>(const ScalarType rhs) const noexcept(/* see below */); // (2)
};
template<typename ScalarType>
std::partial_ordering operator<=>(const ScalarType rhs) const noexcept(/* see below */); // (2)
```
1. 3-way compares two JSON values producing a result of type `std::partial_ordering` according to the following rules:
@@ -18,13 +18,11 @@ bool operator==(
const json_pointer<RefStringTypeRhs>& rhs); // (2)
// since C++20
class json_pointer {
template<typename RefStringTypeRhs>
bool operator==(
const json_pointer<RefStringTypeRhs>& rhs) const noexcept; // (1)
template<typename RefStringTypeRhs>
bool operator==(
const json_pointer<RefStringTypeRhs>& rhs) const noexcept; // (1)
bool operator==(const string_t& rhs) const; // (2)
};
bool operator==(const string_t& rhs) const; // (2)
```
1. Compares two JSON pointers for equality by comparing their reference tokens.
@@ -2,10 +2,8 @@
```cpp
// since C++20
class json_pointer {
template<typename RefStringTypeRhs>
std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept; // *NOPAD*
};
template<typename RefStringTypeRhs>
std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept; // *NOPAD*
```
3-way compares two JSON pointers by lexicographically comparing their sequences of reference tokens: corresponding
@@ -986,8 +986,8 @@ void convert_float_locale_aware(StringType& token, std::size_t decimal_point_pos
{
std::string buffer(token.data(), token.size());
buffer.replace(decimal_point_position, 1, decimal_point);
strtof_by_type(value, buffer.c_str(), &endptr);
complete = endptr == buffer.c_str() + buffer.size();
strtof_by_type(value, buffer.data(), &endptr);
complete = endptr == buffer.data() + buffer.size();
}
if (JSON_HEDLEY_LIKELY(complete))
+2 -2
View File
@@ -10432,8 +10432,8 @@ void convert_float_locale_aware(StringType& token, std::size_t decimal_point_pos
{
std::string buffer(token.data(), token.size());
buffer.replace(decimal_point_position, 1, decimal_point);
strtof_by_type(value, buffer.c_str(), &endptr);
complete = endptr == buffer.c_str() + buffer.size();
strtof_by_type(value, buffer.data(), &endptr);
complete = endptr == buffer.data() + buffer.size();
}
if (JSON_HEDLEY_LIKELY(complete))