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

+1 -1
View File
@@ -70,7 +70,7 @@ Strong guarantee: there are no changes to the view or the document it refers to.
As for `BasicJsonType`, with [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) these exceptions name the JSON
Pointer path of the value within the document, and with
[`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) its bytes in the source text (where
[`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) its bytes in the source text (when
[`materialize()`](materialize.md) sets them).
## Complexity
+1 -1
View File
@@ -22,7 +22,7 @@ Throws [`invalid_iterator.214`](../../home/exceptions.md#jsonexceptioninvalid_it
As for `BasicJsonType`, with [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) the exception names the JSON Pointer
path of the value within the document, and with [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md)
its bytes in the source text (where [`materialize()`](materialize.md) sets them).
its bytes in the source text (when [`materialize()`](materialize.md) sets them).
## Complexity
@@ -22,7 +22,7 @@ Throws [`invalid_iterator.214`](../../home/exceptions.md#jsonexceptioninvalid_it
As for `BasicJsonType`, with [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) the exception names the JSON Pointer
path of the value within the document, and with [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md)
its bytes in the source text (where [`materialize()`](materialize.md) sets them).
its bytes in the source text (when [`materialize()`](materialize.md) sets them).
## Complexity
@@ -24,7 +24,7 @@ Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) i
As for `BasicJsonType`, with [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) the exception names the JSON Pointer
path of the value within the document, and with [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md)
its bytes in the source text (where [`materialize()`](materialize.md) sets them).
its bytes in the source text (when [`materialize()`](materialize.md) sets them).
## Complexity
@@ -24,7 +24,7 @@ Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) i
As for `BasicJsonType`, with [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) the exception names the JSON Pointer
path of the value within the document, and with [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md)
its bytes in the source text (where [`materialize()`](materialize.md) sets them).
its bytes in the source text (when [`materialize()`](materialize.md) sets them).
## Complexity
@@ -75,7 +75,7 @@ Strong guarantee: there are no changes to the view or the document it refers to.
As for `BasicJsonType`, with [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) these exceptions name the JSON
Pointer path of the value within the document, and with
[`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) its bytes in the source text (where
[`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) its bytes in the source text (when
[`materialize()`](materialize.md) sets them).
## Complexity
@@ -63,7 +63,7 @@ Strong guarantee: there are no changes to the view or the document it refers to.
As for `BasicJsonType`, with [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) these exceptions name the JSON
Pointer path of the value within the document, and with
[`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) its bytes in the source text (where
[`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) its bytes in the source text (when
[`materialize()`](materialize.md) sets them).
## Complexity
+15 -8
View File
@@ -134,14 +134,21 @@ document: `#!cpp auto v = json_document::parse(text).root();` does not compile.
- **Macros.** [`JSON_STRICT_NUL_HANDLING`](../api/macros/json_strict_nul_handling.md) and
[`JSON_NOEXCEPTION`](../api/macros/json_noexception.md)/[`JSON_THROW_USER`](../api/macros/json_throw_user.md)
behave the same way they do for `<nlohmann/json.hpp>`. These are the macros that change what the parser accepts or
how it reports errors. With [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) and
[`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md), the exceptions of views name the path
and the bytes of the value as those of `#!cpp basic_json` do; as a view has neither parent pointers nor stored
positions, both are found from the document's index when the exception is thrown, which takes time linear in the
size of the document (only for an exception). One exception has neither: `key()` of an iterator over an array or a
primitive value ([`invalid_iterator.207`](../home/exceptions.md#jsonexceptioninvalid_iterator207)), as a view's
iterator does not know the value it iterates over. The other macros only affect the values `materialize()` produces,
through `BasicJsonType`.
how it reports errors. Two more macros add context to the exceptions of views, as they do for those of
`#!cpp basic_json`:
- With [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md), an exception names the JSON Pointer path of the
value within the document.
- With [`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md), an exception names the bytes of
the value in the source text.
A view has neither parent pointers nor stored positions, so both are found from the document's index when the
exception is thrown. This takes time linear in the size of the document. One exception has neither:
`key()` of an iterator over an array or a primitive value
([`invalid_iterator.207`](../home/exceptions.md#jsonexceptioninvalid_iterator207)), because a view's iterator does
not know the value it iterates over.
The other macros only affect the values `materialize()` produces, through `BasicJsonType`.
## What is different