* Make the value lifecycle inline-friendly
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Compare standard containers without a thread-local depth count
operator== on objects and arrays recursed through the containers' own
operator== and counted the depth in a thread-local variable. Where reading a
thread-local costs a call (macOS), that added about 10% to comparing documents
with many small containers. For the standard containers, walk objects and
arrays directly, compare scalars and strings inline, and pass the depth as an
argument, falling back to compare_iteratively beyond the depth limit. Other
container types keep the previous path.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Address review: owns_memory() helper, leaf compare naming, astyle
- Add detail::owns_memory(value_t), a switch listing every enumerator so
-Wswitch-enum flags it when a type is added; destroy() and the copy
constructor use it instead of hand-written comparisons. Clang emits the
same bitmask test as before.
- Drop the parentheses around the scalar operands in
JSON_IMPLEMENT_SCALAR_CASES; they are only needed for the container
operands (#1530), which the comment now says.
- Build equal_bounded_containers from detail::conjunction so astyle no
longer pads the template brackets.
- Rename equal_scalar() to equal_leaf() and document why it also compares
strings, unlike JSON_IMPLEMENT_SCALAR_FAST.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
The mixed number arms of JSON_IMPLEMENT_OPERATOR cast the integer to
number_float_t before comparing. Past the float's mantissa that cast is lossy:
2^63-2 and 2^63-1 both round to 2^63, so each compares equal to that float
while differing from each other. Equality is therefore intransitive and the
ordering is not a strict weak ordering, which makes std::sort over such values,
or using them as keys in std::set or std::map, undefined behavior.
Compare the two exactly instead. The integer's range is a power of two the
float represents exactly, so a float outside it is ordered by magnitude alone;
inside it, truncating the float is exact, and the integer parts and then any
fractional part decide. The helper hands back a pair whose comparison with the
original operator reproduces that ordering, which keeps every operator's return
type as it was, including partial_ordering for the spaceship.
A NaN operand is returned in both members, so NaN stays false for the
relational operators and unordered for <=>. Values a float represents exactly
still compare equal, so json(1) == json(1.0) is unchanged.
Signed-off-by: qatcod <79017227+qatcod@users.noreply.github.com>
* Add versioned inline namespace
Add a versioned inline namespace to prevent ABI issues when linking code
using multiple library versions.
* Add namespace macros
* Encode ABI information in inline namespace
Add _diag suffix to inline namespace if JSON_DIAGNOSTICS is enabled, and
_ldvcmp suffix if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON is enabled.
* Move ABI-affecting macros into abi_macros.hpp
* Move std_fs namespace definition into std_fs.hpp
* Remove std_fs namespace from unit test
* Format more files in tests directory
* Add unit tests
* Update documentation
* Fix GDB pretty printer
* fixup! Add namespace macros
* Derive ABI prefix from NLOHMANN_JSON_VERSION_*
* Add C++20 3-way comparison operator and fix broken comparisons
Fixes#3207.
Fixes#3409.
* Fix iterators to meet (more) std::ranges requirements
Fixes#3130.
Related discussion: #3408
* Add note about CMake standard version selection to unit tests
Document how CMake chooses which C++ standard version to use when
building tests.
* Update documentation
* CI: add legacy discarded value comparison
* Fix internal linkage errors when building a module
* Rename 'develop' folder to 'include/nlohmann'
* Rename 'src' folder to 'single_include/nlohmann'
* Use <nlohmann/*> headers in sources and tests
* Change amalgamate config file