Commit Graph

12 Commits

Author SHA1 Message Date
Niels Lohmann
a210437b30 Fix CI: json_view value tests without exceptions and with GCC
- ci_test_noexceptions: exception_of() and without_path() exist only
  with exceptions (they catch outside a CHECK_THROWS, which aborts with
  JSON_NOEXCEPTION); compile the comparisons of the conversion, value(),
  and JSON pointer errors only with exceptions as well.
- ci_test_gcc: -Werror=unused-result for static_cast<void>(j.contains(p))
  (GCC's warn_unused_result ignores a cast to void); store the result.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 22:44:33 +02:00
Niels Lohmann
fdcba786d8 Merge branch 'json-view/11-view-access' into json-view/12-view-values
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 22:42:18 +02:00
Niels Lohmann
958fbc3702 Fix CI: json_view access tests without exceptions and on clang 3.6
- ci_test_noexceptions: the element access tests compare the exceptions
  of json_view and basic_json through exception_of(), which catches them
  outside a CHECK_THROWS; with JSON_NOEXCEPTION the first one aborted the
  test. Compile those comparisons only with exceptions.
- clang 3.6: value-initialize a const json_view, as in the tests of
  json-view/10-view-document.
- Format three new documentation examples with the pinned astyle, which
  the "check" job runs once it gets past the amalgamation step.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 22:41:59 +02:00
Niels Lohmann
0dfd1c938e Merge branch 'json-view/10-view-document' into json-view/11-view-access
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 22:39:38 +02:00
Niels Lohmann
a8e9ce9417 Fix CI: json_view tests without exceptions, on clang 3.6, and single header
- ci_test_noexceptions: the helpers that compare the exceptions of
  json_document::parse() and json::parse() catch them outside a
  CHECK_THROWS, so with JSON_NOEXCEPTION the first parse error aborted
  the test. Compile those comparisons only with exceptions, as
  unit-class_parser.cpp does.
- ci_test_gcc: -Werror=unused-result for CHECK_THROWS_AS(json_document::
  parse(...)); assign the result to a dummy document.
- ci_test_compilers_clang (3.6): `const json_view invalid;` needs a
  user-provided default constructor there (CWG 253); value-initialize it.
- ci_test_single_header: json_view.hpp now exists as a single header and
  contains the internal view headers, so unit-json_view_builder.cpp
  includes it instead of the detail headers in that mode, and the test
  is built again with the single header.
- Regenerate single_include/nlohmann/json_view.hpp for the builder change
  merged from json-view/08-view-builder.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 22:39:30 +02:00
Niels Lohmann
bc36fd323b Address the clang-tidy findings of values and JSON pointers
get_string() and number_token() return braced lists; the test compares
floats by their bit patterns instead of with memcmp, uses std::any_of, and
marks a fixed seed, a default member initializer (needed by GCC's
-Weffc++), and a string search.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 14:02:54 +02:00
Niels Lohmann
85f414ae7a Add values and JSON pointers to json_view
basic_json_view gains get<T>(), get_to(), value() with keys and JSON
pointers, and operator[], at(), and contains() with JSON pointers, plus
two functions basic_json has no counterpart for:

- get_string(): the string without a copy (a string_view into the source,
  or into the decoded strings for strings with escapes)
- number_token(): the text of a number as it appears in the source

get<T>() converts arithmetic types, strings (also string_view_t),
std::nullptr_t, std::vector, maps with string keys, and views directly;
floats are converted from the digit layout recorded by the parser with the
library's conversion chain, so the values are bit-identical to parse().
Other types, including user types with from_json(), go through
materialize().

The exceptions are those of basic_json, message included. Where const
basic_json has undefined behavior (a missing key or an index out of range
with operator[] and a JSON pointer), the result is a discarded view;
value() returns the default wherever basic_json catches out_of_range, and
contains() never throws. Array indices of JSON pointers follow
json_pointer's rules (parse_error.106/109, out_of_range.404/410).

Tests compare the conversions of 2,000 generated documents, 20,000 float
tokens (double and float, bit for bit), and every JSON pointer of 1,000
documents with basic_json, and the exceptions for malformed pointers.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 14:02:52 +02:00
Niels Lohmann
daad8ea9b5 Address the clang-tidy findings of element access and iteration
Marks the default initializer of the item's index string (needed by GCC's
-Weffc++) and, in the test, an escaped literal and a comparison of find()
with end(), which is what the test is about.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 14:02:51 +02:00
Niels Lohmann
f80a1a17a9 Add element access, lookup, and iteration to json_view
basic_json_view gains the read-only access functions of basic_json:
operator[] and at() with keys and indices, front(), back(), find(),
contains(), count(), begin()/end(), items() (with structured bindings from
C++17 on), and type_name(). They throw the exceptions (ids and messages)
that the const functions of basic_json throw; where basic_json has
undefined behavior (operator[] with a missing key or an index out of
range, front()/back() of an empty container), the view returns a
discarded view or throws invalid_iterator.214.

Objects are iterated in document order, and all members are visited. With
duplicate keys, lookups find the first member, so that a lookup can stop
at the first match; parse() keeps the last value. Keys of up to 16 bytes
are compared with two overlapping loads instead of memcmp, and most keys
are rejected by their length alone, from the index.

The iterators and items live in detail/view/iterator.hpp, the lookups in
detail/view/lookup.hpp. Tests compare every element and member of 2,000
generated documents with ordered_json, keys of every length around the
load sizes, the exceptions against const basic_json, and the iterators.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 14:02:49 +02:00
Niels Lohmann
207fc01576 Mark the code of json_view that tests cannot reach
The 4 GiB limit and the fallback for an input that parse() accepts but
the view rejects (a bug) are excluded from the coverage; shrink_to_fit()
of an empty document is tested.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 14:02:46 +02:00
Niels Lohmann
aa1a0c7561 Address the clang-tidy findings of json_document and json_view
- the input dispatch takes byte ranges by const reference and reads the
  size once (which also settles a finding of the static analyzer); input
  adapters are taken by value
- the classification of inputs keeps its nested conditional operators, a
  constant expression of C++11 (NOLINT)
- the test's C arrays, fixed seed, and escaped literals are marked, as in
  the other tests

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 14:02:45 +02:00
Niels Lohmann
7b30f0acb2 Test json_document and json_view
unit-json_view.cpp: type queries, size, and empty against basic_json;
materialize() against parse() (json and ordered_json, generated documents,
duplicate keys, 100,000 levels of nesting, parent pointers with
JSON_DIAGNOSTICS); parse errors and their messages equal to parse() for
malformed inputs and all option combinations; NUL and BOM; borrowed and
owned inputs (strings, C strings, literals, vectors, string_view, streams,
wide strings, parse_copy, and iterator ranges over pointers, vectors,
strings, and lists); reuse with read(); moves; shrink_to_fit() of the index
and of the decoded strings; source offsets.

unit-json_view_macros.cpp includes the header without
JSON_TEST_KEEP_MACROS, as users do: the view must not depend on the macros
json.hpp undefines, and must not leak its own.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 09:54:05 +02:00