json_view: address review of the exception diagnostics

- value_path(): check for the empty stack where the last frame is popped,
  so that the loop is `for (;;)`; update the frame only after the target
  check; document that the frame reference is not used after pop_back()
  or push_back() (and add a test with deep documents to run under a
  sanitizer)
- value_range(): flip the container check to remove a level of nesting
- diagnostics(): wrap the whole function in the macro check, and compute
  the path before the bytes, so that nothing is computed when there is no
  path; the function stays a template
- error_site: separate constructors for the two configurations
- site_of(): static_assert that it is called with a view
- document why the throw helpers without an error_site have none
- pointer.hpp: do not split a comment around the template header
- docs: "when materialize() sets them"; list the effects of
  JSON_DIAGNOSTICS and JSON_DIAGNOSTIC_POSITIONS separately

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5NasBf4ToHzdcoNEPAJhS
This commit is contained in:
Claude committed 2026-10-31 08:08:18 +00:00
1 parent e1645876e6
commit b1434350d7
12 files changed
+180 -139

No files matched your search

+20
View File
@@ -512,6 +512,26 @@ TEST_CASE("json_view exceptions name the path and the bytes of the value")
CHECK(exception_of_call([&] { static_cast<void>(d.root()["a"][2]["n"][0].get<int>()); }) == expected);
}
SECTION("deep documents with siblings after every nested container")
{
// the search for the path pushes and pops one frame per level (the
// stack reallocates while it grows, and shrinks again at every
// sibling): run under a sanitizer, a reference to a popped or moved
// frame would show here
std::string text = "7";
for (int level = 0; level < 40; ++level)
{
text = R"([[1, [2]], )" + text + R"(, {"k": [3, {"l": [4]}]}, [5, [6, [7]]]])";
}
CAPTURE(text)
const json j = json::parse(text);
const json_document d = json_document::parse(text);
check_exceptions(d.root(), j);
json_editable_document e = json_editable_document::parse(text);
e.set(e.root()[0][0], 9);
check_exceptions(e.root(), e.root().materialize());
}
SECTION("examples")
{
const std::string text = R"({"people": [{"name": "a", "age": 1}, {"name": "c", "age": "x"}], "o": {"k": 1}})";