Conversation
Copy and move already transferred start_pos/end_pos, but swap() only exchanged the payload, so std::swap left positions on the wrong object. Also pin copy/move/swap behavior with tests. Signed-off-by: elix3r <157088510+22elix3r@users.noreply.github.com>
|
The type-specific swap functions below this one don't swap, and they can't because they take type-specific values, so I'm not sure what those should do, if anything. |
|
Those overloads swap only the contained The other argument is not a |
|
To spell out what "part 1 of #5420" leaves open — and one gap inside part 1 itself: Item 1 is not complete. Copy, move and swap are now asserted, but the mutation case is not:
Item 2 — input adapters. None of it: wide strings (where Item 3 — user-driven SAX. Untouched. A user-constructed Item 4 — Note the Generated by Claude Code |
🔴 Amalgamation check failed! 🔴The source code has not been amalgamated and/or formatted correctly. 📎 A ready-to-apply patch is attached to the failed workflow run as the git apply amalgamation.patchThis does not require installing astyle yourself. |
Swap was only part of the issue. Pin mutation (parent/sibling spans stay, replacements are npos), input adapters including wide strings and BOM, user SAX without a lexer, trailing commas with positions, and accept()/sax_parse() ignore_trailing_commas. Document UTF-8 byte-offset semantics, copy/move/swap, and that type-specific container swap leaves positions in place. Restore amalgamated header formatting. Signed-off-by: elix3r <157088510+22elix3r@users.noreply.github.com>
|
Follow-up for the review: this is no longer just part 1 of #5420. Item 1 (lifetime). Copy/move/swap stay. Mutation is now pinned: Item 2 (adapters). Covered: Item 3 (user SAX). A user-constructed Item 4 (trailing commas).
|
Is that useful? If the content is no longer what was parsed from that document, should it continue to refer to the positions in the document, possibly creating an inaccurate error message later? Related to this comment:
|
|
Thanks for this — the underlying finding is real and well-diagnosed: We're folding that fix into our own diagnostic-positions work (the #5474/#5482 stack for #5417/#5420), which took a different structural approach to the test-file duplication (deleting — closed by Claude Code on behalf of @nlohmann |
Summary
With
JSON_DIAGNOSTIC_POSITIONS, copy construction copiesstart_pos/end_posand move construction resets the source tonpos, butbasic_json::swaponly swapped the payload.std::swaptherefore left diagnostic positions attached to the wrong object. That is a behavior fix, not just extra coverage.The rest of #5420 was test/docs holes around that API. This PR now covers them instead of leaving a follow-up.
Related Issue
Fixes #5420
Changes Made
Behavior
start_position/end_positioninbasic_json::swap()when positions are enabled (type-specificarray_t/object_t/string_t/binary_toverloads still leave positions on thebasic_jsonobject)Tests (the rest of #5420)
npos)basic_jsonvalues, plus type-specific container swapoperator[],push_back,eraseleave parent/sibling spans pointing at the original text; replacements arenposistringstream,ifstream, iterator pairs, contiguousvector, UTF-8 BOM (start_pos() == 3)u16string/u32stringfrom_cbor/from_msgpack/from_ubjson/from_bjdata/from_bson) yieldnposjson_sax_dom_parser(no lexer) yieldsnposignore_trailing_commas:end_poscovers the skipped comma;accept()/sax_parse()with the flag on (the hole Test suite: unit-class_parser_diagnostic_positions.cpp has drifted from unit-class_parser.cpp — deduplicate via define-based recompilation #5417 / Exercise trailing commas with diagnostic positions enabled #5431 left open)Docs
nposTesting
Commands executed:
python3 tools/amalgamate/amalgamate.pyis not sufficient by itself;single_include/nlohmann/json.hppis restored fromdevelopwith only theswapchange (CI amalgamation check failed on the first commit because amalgamate.py was run without astyle)cmake -S . -B build -DJSON_BuildTests=ON -DCMAKE_BUILD_TYPE=Debug -DJSON_FastTests=ONcmake --build build --target test-diagnostic-positions_cpp11 test-class_parser_diagnostic_positions_cpp11 test-deserialization_cpp11./tests/test-diagnostic-positions_cpp11 --no-skip -tce='*downloaded*'./tests/test-class_parser_diagnostic_positions_cpp11 --no-skip -tce='*downloaded*'./tests/test-deserialization_cpp11 --no-skip -tce='*downloaded*'Results:
Notes
Assignment already swapped positions (
operator=(basic_json other)). Memberswapwas the hole. Positions describe a span in the original parse input; they are not recomputed when the value is later mutated.make amalgamate.