Address review: if/else for container positions, clearer next field

- the opening bracket of a container sets positions with an if/else instead
  of a ternary, and the frame takes its start from positions
- the closing bracket of a container is found in nested if/else; the parent's
  last_end is taken from positions, so it is npos whenever no range is set
- architecture.md: the next field reads "or 0 if it was not; all other
  values: 0" instead of "else 0; otherwise 0"

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-10-28 09:13:29 +01:00
1 parent c6708926f6
commit b85fe6e4f5
3 files changed
+35 -27

No files matched your search

+1 -1
View File
@@ -203,7 +203,7 @@ packet-beta
| 2-3 | `extra` | `uint16_t` | numbers: the number of integer digits (low byte) and fraction digits (high byte), 255 for more; objects: the number of their key hash index (1-based), or 0; otherwise 0 |
| 4-7 | `off` | `uint32_t` | where the value starts: the first byte after a string's opening quote (or its position in the buffer of decoded strings), the first byte of a number or literal, the bracket of an array or object |
| 8-11 | `len` | `uint32_t` | strings: the length after decoding; floats and literals: the length of the token; arrays and objects: the number of elements |
| 12-15 | `next` | `uint32_t` | arrays and objects: the number of nodes of the subtree, including the node itself; strings with escapes: the position of the opening quote in the source plus one if the document was parsed with [`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md), else 0; otherwise 0 |
| 12-15 | `next` | `uint32_t` | arrays and objects: the number of nodes of the subtree, including the node itself; strings with escapes: the position of the opening quote in the source plus one if the document was parsed with [`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md), or 0 if it was not; all other values: 0 |
<p class="nj-table-caption" markdown>Fields of a node, by their byte offset within the 16-byte node. Integers use bytes 8-15 differently, see below.</p>
+17 -13
View File
@@ -320,15 +320,13 @@ BasicJsonType materialize(const document_data& d, const node* n)
const bool object = n->kind == node_kind::object;
#if JSON_DIAGNOSTIC_POSITIONS
// (moved containers are also new)
const std::size_t start = (n->flags & node_flags::is_new) == 0 && n->off < d.size ? std::size_t{n->off} :
std::string::npos;
if (start == std::string::npos)
if ((n->flags & node_flags::is_new) != 0 || n->off >= d.size)
{
positions.clear();
}
else
{
positions.set(start, start + 1);
positions.set(std::size_t{n->off}, std::size_t{n->off} + 1);
}
#endif
if (object)
@@ -351,7 +349,7 @@ BasicJsonType materialize(const document_data& d, const node* n)
// own bracket is the last thing read)
open[depth++] = frame{nav::first(d, n), nav::end(d, n), object
#if JSON_DIAGNOSTIC_POSITIONS
, start, positions.end
, positions.start, positions.end
#endif
};
break;
@@ -395,22 +393,28 @@ BasicJsonType materialize(const document_data& d, const node* n)
if (f.pos == f.end)
{
#if JSON_DIAGNOSTIC_POSITIONS
const std::size_t end = f.start == std::string::npos || f.last_end == std::string::npos ? std::string::npos :
position_source::container_end(d.base[0], d.size, f.last_end);
if (end == std::string::npos)
if (f.start == std::string::npos || f.last_end == std::string::npos)
{
positions.clear();
}
else
{
// the closing bracket, as the lexer reports it (end_object()
// and end_array() only read its end; the start of the
// container was set when it was opened)
positions.set(end - 1, end);
const std::size_t end = position_source::container_end(d.base[0], d.size, f.last_end);
if (end == std::string::npos)
{
positions.clear();
}
else
{
// the closing bracket, as the lexer reports it (end_object()
// and end_array() only read its end; the start of the
// container was set when it was opened)
positions.set(end - 1, end);
}
}
if (depth > 1)
{
open[depth - 2].last_end = end;
open[depth - 2].last_end = positions.end;
}
#endif
if (f.object)
+17 -13
View File
@@ -6427,15 +6427,13 @@ BasicJsonType materialize(const document_data& d, const node* n)
const bool object = n->kind == node_kind::object;
#if JSON_DIAGNOSTIC_POSITIONS
// (moved containers are also new)
const std::size_t start = (n->flags & node_flags::is_new) == 0 && n->off < d.size ? std::size_t{n->off} :
std::string::npos;
if (start == std::string::npos)
if ((n->flags & node_flags::is_new) != 0 || n->off >= d.size)
{
positions.clear();
}
else
{
positions.set(start, start + 1);
positions.set(std::size_t{n->off}, std::size_t{n->off} + 1);
}
#endif
if (object)
@@ -6458,7 +6456,7 @@ BasicJsonType materialize(const document_data& d, const node* n)
// own bracket is the last thing read)
open[depth++] = frame{nav::first(d, n), nav::end(d, n), object
#if JSON_DIAGNOSTIC_POSITIONS
, start, positions.end
, positions.start, positions.end
#endif
};
break;
@@ -6502,22 +6500,28 @@ BasicJsonType materialize(const document_data& d, const node* n)
if (f.pos == f.end)
{
#if JSON_DIAGNOSTIC_POSITIONS
const std::size_t end = f.start == std::string::npos || f.last_end == std::string::npos ? std::string::npos :
position_source::container_end(d.base[0], d.size, f.last_end);
if (end == std::string::npos)
if (f.start == std::string::npos || f.last_end == std::string::npos)
{
positions.clear();
}
else
{
// the closing bracket, as the lexer reports it (end_object()
// and end_array() only read its end; the start of the
// container was set when it was opened)
positions.set(end - 1, end);
const std::size_t end = position_source::container_end(d.base[0], d.size, f.last_end);
if (end == std::string::npos)
{
positions.clear();
}
else
{
// the closing bracket, as the lexer reports it (end_object()
// and end_array() only read its end; the start of the
// container was set when it was opened)
positions.set(end - 1, end);
}
}
if (depth > 1)
{
open[depth - 2].last_end = end;
open[depth - 2].last_end = positions.end;
}
#endif
if (f.object)