Follow-up to #5342, which fixed the parser callback leaving a discarded
member behind when an array or a value under an object key was rejected.
The documentation of parser_callback_t only stated that discarded values
in structured types are skipped, without saying that this covers object
parents and that the key is removed along with the value, so there was no
way to tell the fixed behavior from the buggy one.
Spell out the discarding rules, add an example that exercises the cases
the fix repaired, and correct the return value description: a discarded
top-level value is replaced by null, not by "an empty discarded object".
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* docs: use HTTPS for the astyle and cppcheck links in README
Both links were still `http://`. `astyle.sourceforge.net` serves HTTPS
directly; `cppcheck.sourceforge.net` redirects to
`https://cppcheck.sourceforge.io`, which is also the URL already used in
`docs/mkdocs/docs/community/quality_assurance.md`, so the redirect is
skipped here.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* CI: suppress -Wc2y-extensions for Clang
Clang 22.1 (now shipped by silkeh/clang:latest) diagnoses __COUNTER__ as a
C2y extension, and does so in C++ mode as well. Under -Weverything -Werror
this breaks every ci_test_clang_cxx* / ci_test_clang_libcxx_cxx* target,
independently of the code under test.
The library itself does not use __COUNTER__; all diagnostics originate in
vendored Doctest (DOCTEST_ANONYMOUS, used by TEST_CASE and SECTION).
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* docs: document RFC 8259 / JSONTestSuite compliance and parse() vs operator>> strictness
The compliance story lived only in tests/src/unit-testsuites.cpp, so
drive-by comparisons kept claiming the library "does not fully pass
JSONTestSuite". Make it discoverable:
- README: add a "Standards compliance" note stating that both nst
JSONTestSuite revisions run in CI, that all mandatory y_/n_ cases pass
through the strict parse() entry point, and listing the deliberate
implementation-defined i_ choices (unbounded nesting, silent BOM
stripping, noncharacters forwarded, strict rejection of invalid UTF-8
and lone surrogates, out_of_range.406 on numeric overflow).
- features/parsing: add a "Strictness and trailing data" section
documenting that parse() is strict and rejects trailing data while
operator>> follows relaxed iostream semantics (parses one value and
leaves the stream positioned after it) -- the single place a naive
test yields a "non-compliant" result.
Documentation only; no parser behavior change. Closes#5290.
Signed-off-by: manon <youdie006@users.noreply.github.com>
* docs: correct test-data vendoring and parse()/operator>> claims per review
- README: the JSONTestSuite data is downloaded from nlohmann/json_test_data at
configure time, not vendored/committed; say so.
- README: only the updated suite runs y_ and n_ cases through strict parse();
the original suite's y_ cases go through operator>>. Narrow the claim.
- parsing/index.md and operator_gtgt.md: note that operator>> consumes a number's
terminating byte, so concatenated numbers must be whitespace-separated (1 2
works, 1true does not); structural and literal values are unaffected.
Signed-off-by: manon <youdie006@users.noreply.github.com>
---------
Signed-off-by: manon <youdie006@users.noreply.github.com>
Co-authored-by: manon <youdie006@users.noreply.github.com>
is_comparable used a flat && chain to both exclude json_pointer/string
comparisons (added for #4621) and check whether Compare(A, B) is well-formed.
Naming std::is_constructible<decltype(...)> as a later operand of that chain
still causes the decltype to be substituted regardless of the first
operand's value, since the operands aren't lazily deferred like
std::conjunction would defer them. That instantiates the transparent
std::equal_to<>::operator() used by ordered_json, whose noexcept-specifier
evaluates the deprecated json_pointer/string operator==, which Clang (unlike
GCC in this case) warns about even though the result is discarded.
Split is_comparable so the Compare(A, B) checks live in a separate helper
that is only referenced from the specialization selected when
is_json_pointer_of is false, so the decltype is never written when A/B are
a json_pointer/string pair, regardless of compiler.
Signed-off-by: Niels Lohmann <niels.lohmann@gmail.com>
operator>>'s notes state that it leaves the stream positioned right
after the parsed value, so that concatenated JSON values can be read
back to back. That does not hold when the value is a number: a number
is only terminated by the character that follows it, and the lexer's
unget() is simulated (it rewinds only the lexer's own bookkeeping),
so that character stays consumed from the stream.
Document the actual behaviour: the guarantee holds for all value types
except numbers, which must be followed by whitespace. Also qualify the
cross-reference on the JSON Lines page, which repeated the unqualified
claim.
Documentation only; the behaviour itself is tracked in #5340.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* reject CBOR array/map length equal to the indefinite-length marker
Signed-off-by: Angadi Yashaswini <angadi@digiscrypt.com>
* reject CBOR lengths that do not fit in std::size_t via value_in_range_of
Signed-off-by: Angadi Yashaswini <angadi@digiscrypt.com>
---------
Signed-off-by: Angadi Yashaswini <angadi@digiscrypt.com>
This adds a std::isfinite check to the UBJSON floating-point parsing path, throwing out_of_range.406 on overflow. This makes the UBJSON parser's behavior consistent with the normal JSON parser. Fixes#5322.
Signed-off-by: AJ369ninja <abhishek.j@iitg.ac.in>
Co-authored-by: AJ369ninja <abhishek.j@iitg.ac.in>
* validate ndarray element types in write_bjdata_ndarray
Signed-off-by: Angadi Yashaswini <angadi@digiscrypt.com>
* read ndarray elements through get<> instead of a fixed union member
_ArrayType_ names the wire type, not how the value is stored: parsing
keeps a non-negative integer as number_unsigned while the C++ API keeps
an int literal as number_integer. Selecting the union member from the
type marker therefore reads the inactive alternative for one of the two,
so read through get<> instead, which dispatches on the active member.
Also reject a negative _ArraySize_ entry, which is not a usable
dimension, and cover the parse-built path in the tests.
Signed-off-by: Angadi Yashaswini <angadi@digiscrypt.com>
---------
Signed-off-by: Angadi Yashaswini <angadi@digiscrypt.com>
- warn about BSON marker 0x11 interoperability in both directions
- explain subtype-less binary normalization to subtype 0x00
- add a round-trip test for binary values without a subtype
Signed-off-by: YingqiDuan <141370165+YingqiDuan@users.noreply.github.com>
Both had zero documentation anywhere in docs/mkdocs/. The tuple/pair
gap was first spotted in the very first git-log audit pass but never
turned into an actionable todo, so it persisted uncaught across four
subsequent passes.
- Document basic positional std::pair/std::tuple <-> json array
conversion, plus #5016's reference-extraction capability
(get<std::tuple<T&, T&>>() returning references into the stored
array elements).
- Document #5205's new json-from-C++20-range-view constructor
(e.g. nums | std::views::filter(...)).
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Closes#3106. set(JSON_Diagnostics ON) before find_package() has no
effect on a package built and installed elsewhere (Homebrew, vcpkg, a
system package, etc.) -- the compile definition is baked into the
exported nlohmann_jsonTargets.cmake at install time and the generated
config script never re-reads that variable. Verified empirically
against the real Homebrew-installed 3.12.0 package: the exported
target carries a fixed $<$<BOOL:OFF>:JSON_DIAGNOSTICS=1>, and the
suggested set(JSON_Diagnostics ON) snippet produces no change in
exception output.
Documents the actual working fix (overriding the imported target's
INTERFACE_COMPILE_DEFINITIONS property after find_package()) and the
multi-target "JSON_DIAGNOSTICS redefined" pitfall reported earlier in
the issue thread.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* Add iterator+sentinel tests and docs for binary deserializers
This commit extends the C++20 ranges support (iterator+sentinel pairs) to the
binary format deserializers from_cbor, from_msgpack, from_ubjson, from_bjdata,
and from_bson, matching what was already done for parse(), accept(), and
sax_parse().
Changes:
- Add istreambuf_sentinel helper to test_utils.hpp for EOF detection in tests
- Add 5 new test cases that read binary files directly via
std::istreambuf_iterator<char> + sentinel, without pre-buffering
- Update documentation for all 5 from_* functions to document overload (3)
with SentinelType parameter
- All tests pass; verified against existing test suite data
- Fix potential buffer over-read warning in heterogeneous iterator test
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Merge iterator+sentinel overloads and fix ambiguity/CI issues
Address PR review feedback and CI failures:
- Merge the separate same-type and sentinel-type iterator overloads of
parse(), accept(), sax_parse(), and the five from_* binary deserializers
into a single overload with SentinelType defaulted to IteratorType,
as suggested in review. Applied the same simplification to the
detail::input_adapter() free functions.
- Fix a latent ambiguity: some compilers (e.g. GCC 4.8) unreliably SFINAE
the operator!= detection for std::nullptr_t against container/string
types, making calls like parse(s, nullptr, ...) ambiguous with the
compatible-input overload. can_compare_ne now explicitly excludes
std::nullptr_t as a SentinelType.
- Use a named enable_if_t template parameter instead of an unnamed
function parameter for the SFINAE guard, fixing a clang-tidy
hicpp-named-parameter/readability-named-parameter failure.
- Update parse.md, accept.md, sax_parse.md, and the five from_*.md pages
to document the merged overload instead of separate (2)/(3) overloads,
also fixing an over-160-char line that broke the documentation
style_check CI job.
- Rework the BSON iterator+sentinel test to parse a BSON file already
present in the test suite instead of writing/deleting a temp file.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix -Wunneeded-internal-declaration for CustomSentinel in test
CustomSentinel lives in an anonymous namespace (internal linkage), and
the library's parse loop only ever evaluates the iterator-first
direction (it != last), so the reversed-order friend operator!= was
never referenced. Clang's -Weverything flags such unused internal
declarations as an error. Drop the unused overload; the used direction
is enough to satisfy can_compare_ne's either-order detection.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix clang-tidy hicpp-named-parameter and misc-const-correctness
- Drop the unused reversed-order operator!= overload from
utils::istreambuf_sentinel (only iterator != sentinel is ever
evaluated) and name the remaining friend's sentinel parameter, fixing
hicpp-named-parameter/readability-named-parameter.
- Mark the istreambuf_iterator first/last helper variable const in the
five binary-format sentinel tests, fixing misc-const-correctness.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix clang-tidy misc-const-correctness in heterogeneous sentinel test
json_str is only read via .data()/.size() and never reassigned, so
clang-tidy correctly flags it as const-able. Verified against the exact
CI job (silkeh/clang:dev, ci_clang_tidy target) by running clang-tidy
directly on this file plus the five binary-format sentinel tests
touched by prior commits; all are now clean.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix discussion #4209: custom BinaryType direct assignment and extraction
When a custom BinaryType is configured (other than the default std::vector<uint8_t>),
users can now:
1. Assign values of that type directly to create binary values (not arrays)
2. Extract binary values back to that type with get<>()
3. Extract arrays to that type (for backward compatibility)
Implementation:
- Add is_compatible_binary_type trait to centralize SFINAE condition
- Update to_json to accept custom BinaryType values directly
- Update from_json to handle both binary and array inputs for custom BinaryType
- Add #include <vector> with IWYU comment to from_json.hpp
- Add comprehensive tests for assignment and array extraction
- Update binary_t documentation with example
This is purely additive and invisible to the default nlohmann::json alias, which
continues to treat std::vector<uint8_t> as arrays.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix CI: missing include and const-correctness
- Add #include <vector> to type_traits.hpp for the new
is_compatible_binary_type trait's std::vector<std::uint8_t> reference
(caught by cpplint's include-what-you-use check)
- Mark test-local json variables const where never reassigned
(caught by clang-tidy's misc-const-correctness check)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Migrate ci_icpc/ci_test_compilers_gcc_old/ci_infer off custom json-ci image
Replaces the last three consumers of ghcr.io/nlohmann/json-ci with official
images: ci_icpc now uses Intel's own intel/oneapi-hpckit:2023.2.1-devel-ubuntu22.04
(the last release with classic icc/icpc before Intel dropped it in oneAPI
2024.0), ci_test_compilers_gcc_old installs old GCCs on official ubuntu:20.04
via the same PPA/archive setup the custom image used (working around
actions/checkout's incompatibility with official gcc:4/5/6 images), and
ci_infer runs directly on ubuntu-latest, fetching Facebook's official Infer
release tarball inline instead of a maintained image. No job in
ubuntu.yml references the custom image anymore.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Update quality-assurance compiler table for CI image migration
Reflects the ci_icpc/ci_test_compilers_gcc_old container migration: the
old-GCC jobs (4.8/4.9/5/6) now compile inside official ubuntu:20.04 rather
than the custom Focal-based json-ci image (same OS, just now attributed to
the official image), and ci_icpc now uses Intel's official
intel/oneapi-hpckit:2023.2.1-devel-ubuntu22.04, bumping the reported ICC
version from 2021.5.0 to 2021.10.0 and the OS from Ubuntu 20.04.3 to 22.04.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix CI failures from the json-ci image migration
- ci_icpc: the official intel/oneapi-hpckit image has no CMake preinstalled
(the custom image bundled one); add the missing lukka/get-cmake step.
- ci_test_compilers_gcc_old: official ubuntu:20.04 has no build tool, so
CMake's default Unix Makefiles generator failed with "CMAKE_MAKE_PROGRAM
is not set"; install make alongside the PPA-provided g++.
- ci_infer: Infer v1.1.0's bundled Clang frontend can't parse GCC 14's
headers (ubuntu-latest's default toolchain), failing with parse errors in
<bits/unicode.h>; bump to the latest release, v1.3.0, whose newer bundled
frontend understands them (release asset also renamed upstream from
infer-linux64-v1.1.0.tar.xz to infer-linux-x86_64-v1.3.0.tar.xz).
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix ci_test_compilers_gcc_old: g++-6 missing from xenial-only archives
My inline PPA/archive replication only added the xenial main/universe
suites, but g++-6 isn't available there ("has no installation candidate").
The original custom Dockerfile also pulled from bionic main/universe and
xenial-updates main/universe; add those back to match.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix ci_test_compilers_gcc_old: install git for CMake's FetchContent tests
Official ubuntu:20.04 ships no git at all (actions/checkout only succeeded
via its API-download fallback). The cmake_fetch_content(2) tests invoke
CMake's own ExternalProject_Add, which needs a real git binary and failed
with "could not find git for clone of json-populate". Install git alongside
the other build prerequisites.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix ci_icpc: drop redundant setvars.sh sourcing
Unlike the old custom image, the official intel/oneapi-hpckit image already
has the oneAPI environment (icc/icpc on PATH) baked in at the container
level. Explicitly re-sourcing setvars.sh in the Build step failed with
"setvars.sh has already been run. Skipping re-execution." (exit code 3,
aborting the step under `sh -e`). Drop the now-unnecessary sourcing.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix ci_icpc: exclude classic ICC from the std::span regression test
Bumping to Intel's official intel/oneapi-hpckit:2023.2.1 image (see previous
commit) also bumped classic icc/icpc from 2021.5.0 to 2021.10.0. The newer
version's __has_include(<span>) now returns true, but it still can't
actually compile std::span/std::as_bytes usage:
error: namespace "std" has no member "as_bytes"
error: namespace "std" has no member "span"
Exclude __ICC/__INTEL_COMPILER the same way _LIBCPP_VERSION is already
excluded for issue #4490.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix amalgamation/style check: indent comment per astyle
Verified with the pinned astyle 3.4.13 (make install_astyle) locally;
no further diff.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix ci_icpc: skip UTF-8 u8-literal comparison test on classic ICC
test-deserialization_cpp20 failed:
ERROR: CHECK( j2["emoji"] == "😀" ) is NOT correct!
check_utf8() only guards against MSVC's ANSI-codepage quirk (its docstring
example), but classic ICC has an analogous problem: it doesn't encode a
narrow string literal containing non-ASCII source characters as UTF-8,
so comparing a decoded u8R"(...)" literal against a narrow literal with
the same characters fails. Extend the existing guard.
Verified with the pinned astyle 3.4.13; no diff.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* 📝 Fix documentation gaps found in a full GitHub Discussions review
Reviewed all 1008 GitHub Discussions (2020-2026) for recurring questions
that better or more visible documentation would have avoided. Adds/expands
documentation for ~26 distinct gaps, including:
- New "Debugging" page collecting natvis, GDB pretty printer, LLDB status,
and JSON_DIAGNOSTICS pointers (previously scattered/undiscoverable)
- Thread-safety and schema-validation FAQ entries
- StringType's char-based requirement (no wstring/u16string/u32string)
- Brace-initialization-yields-arrays warning directly on the constructor
reference page (previously only in the FAQ, missed by users reading
the constructor docs)
- std::any exclusion from get<T>(), with a manual-dispatch example
- Non-string-keyed std::map serializing as an array of pairs
- ordered_json compatibility with NLOHMANN_DEFINE_TYPE_* macros
(already worked, was undocumented)
- std::array truncation on size-mismatched conversion (no exception)
- static_cast vs. get<std::optional<T>>() divergence
- Recipe for omitting a std::optional field instead of emitting null
- No built-in nesting-depth limit during parsing + a callback-based
workaround recipe
- Recipe for streaming a large homogeneous array via parser callbacks
- operator>> stream-position semantics for concatenated JSON values
- JSON Pointer array-vs-object creation rule for non-existing paths
- CMake target name (nlohmann_json_modules) needed to link C++20 modules
- ESP-IDF/PlatformIO: no official package, link to a community fork
- get(key, default) as the Python dict.get() equivalent
- reserve() recipe for pre-allocating array capacity
- JSONC as an alias for the existing ignore_comments/ignore_trailing_commas
combination (distinct from the unsupported JSON5)
- items() dereferenced-element type: decltype() idiom + detail-namespace
stability caveat
- Various macro/type-conversion limitations (MSGPACK_DEFINE_ARRAY
equivalent, char-array round-tripping, ADL serializer macro gap)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* 🎨 fix format
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix container input_adapter SFINAE for lvalue-only ADL begin/end (#111)
The container overload of json::parse(c) / accept(c) / sax_parse(c, ...)
silently dropped from overload resolution for user types whose ADL
begin(T&) / end(T&) accepted only non-const lvalue references
(a legitimate pattern matching std::begin semantics). This was because
the detection code used std::declval<ContainerType>() which synthesized
an rvalue, and the rvalue failed to bind to lvalue-only ADL functions.
Fix by making both the outer input_adapter(ContainerType&&) and the
factory's create(ContainerType&&) forwarding references, preserving the
caller's value category and constness via reference collapsing. This
ensures detection (std::declval) and actual use (std::forward) always
match without needing decay/remove_reference.
- Rewrite input_adapters.hpp container overload with forwarding refs
- Add regression tests for lvalue-only non-const ADL begin/end
- Add regression test for rvalue containers (no breakage)
- Update API docs (parse, accept, sax_parse, from_*) to clarify
that begin/end must match std::begin/std::end semantics
- Add version history notes for 3.13.0
- Regenerate amalgamation
Second-order effect: binary_reader.hpp's internal call to
input_adapter(number_vector) now deduces iterator vs const_iterator
based on the lvalue; functionally harmless (iterator_input_adapter is
iterator-type-agnostic), verified via unit-ubjson/unit-bjdata tests.
Closes remaining limitation from #4354 / PR #5218 (todo 106).
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Avoid strlen() in test container to fix Codacy CWE-126 flag
Suppressing the strlen()-based CWE-126 warning with NOLINT/nosec
comments only silenced clang-tidy and the standalone Flawfinder
Action; Codacy's own analysis (which also flags this pattern and
doesn't honor those suppression comments) still reported it as a new
issue, plus flagged the near-duplicate begin/end pair as cloned code.
Store the buffer's size explicitly in MyContainerNonConstADL instead
of computing it via strlen() in end(), which removes the flagged
pattern outright and also de-duplicates the struct from the existing
MyContainer's char*-based begin/end pair.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Avoid trailing return type to satisfy clang-tidy fuchsia-trailing-return
The forwarding-reference input_adapter(ContainerType&&) entry point was
written with an auto/trailing-decltype return type, but this project's
ci_clang_tidy job enables the fuchsia-trailing-return check as an
error, which rejects it. The return type only depends on the template
parameter ContainerType, not on the runtime parameter, so it can be
written as an ordinary leading return type instead - no functional
change.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Avoid C-style array in test to satisfy clang-tidy avoid-c-arrays
clang-tidy's cppcoreguidelines/hicpp/modernize-avoid-c-arrays checks
flagged the char raw_data[] declaration used to reproduce the
lvalue-only non-const ADL begin/end scenario. Use std::string instead
and take a mutable pointer via &raw_data[0], which is the standard
way to get a non-const char* into a string's buffer under C++11
(std::string::data() only returns non-const in C++17 and later).
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* 📝 Fix stale 3.12.x placeholder in operator_ne.md version history
PR #5253 (removing the hand-written operator!= to fix #3868/P2468R2)
merged after the earlier 3.12.x -> 3.13.0 global sweep, so its new
version-history entries were written with the stale placeholder.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* 🐛 Fix stale twitter.com link in docset.json
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* 📝 Document a duplicate-object-key rejection recipe
RFC 8259 leaves handling of duplicate object keys to the implementation;
this library silently keeps only the last value for a repeated key.
Discussion #5085 asked for an opt-in rejection mode. Decision: don't
change library behavior, but document the existing parser-callback
workaround instead.
Adds a "Recipe: rejecting duplicate object keys" section to
parser_callbacks.md, adapted from a community-contributed workaround.
Fixed an off-by-one bug in the original snippet: object_start reports
the depth of the object's parent, while key events inside that object
report depth+1, so indexing the per-depth key set with the same depth
in both places caused an out-of-bounds access on nested objects.
Verified the published snippet compiles and behaves correctly for flat
duplicates, nested duplicates, sibling objects sharing key names, and
arrays of objects.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Cross-link the duplicate-key recipe with the existing object_t behavior docs
object_t.md and features/types/index.md already document that duplicate
object keys resolve to an unspecified value (RFC 8259 leaves this to the
implementation). The new recipe's intro overstated this as a guaranteed
"last value wins" rule, which isn't true in general -- parsing text keeps
the last value, but constructing from an initializer list keeps the first.
Reworded the recipe to point at object_t's "unspecified" behavior instead
of asserting a specific rule, and added cross-links from both existing
pages to the new recipe.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Turn the duplicate-key recipe into a standalone, compiled example
Replace the inline code fence in the "rejecting duplicate object keys"
recipe with a proper docs/mkdocs/docs/examples/*.cpp + .output pair,
included via --8<-- like every other example on the site. The .output
file was generated by running it through the project's actual example
build (docs/Makefile: single_include, -std=c++11, -DJSON_USE_GLOBAL_UDLS=0)
and cross-checked with `make check_output`, and the source passes the
pinned astyle 3.4.13 formatting unchanged.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix#3868: Remove operator!= to enable P2468R2 rewritten candidate synthesis
Under C++20 P2468R2, a hand-written operator!= suppresses the compiler's
rewritten-candidate synthesis for operator==, preventing heterogeneous
comparisons like `std::string s; json j; s == j;` from compiling.
Fix by removing the hand-written operator!=, allowing the compiler to
synthesize != as !(a==b) in all language modes (C++20 member functions
and pre-C++20 friend functions).
Behavior change: operator!= now returns !(a==b) unconditionally, including
for special values like NaN and discarded. This means:
- NaN != NaN now returns true (matches IEEE-754 semantics)
- discarded != x now returns true for any x (matches !(discarded == x))
This also fixes underlying defects in previously-working code:
- Restores direct == comparison for views vs json (reverts std::ranges::equal
workaround added in PR #3950 to dodge this bug)
- Re-enables std::string == json comparisons (uncomments check in
unit-constructor1.cpp)
Fixes: #3868, #3979
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* 🚨 fix warning
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
PR #5248 added a 5th JSON_HAS_RANGES exclusion branch to
macro_scope.hpp (nvcc CUDA 12.0.x/12.1.x, fixed in 12.2, issue #3907)
shortly after #5252 added the "Known compiler/stdlib exclusions"
list to json_has_ranges.md, so the new branch was missing from the
just-added doc section. Bring the list back to parity with the code
(5 exclusion branches, 5 documented).
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix stale Clang -Weverything suppression comments; eliminate -Wno-missing-noreturn
cmake/clang_flags.cmake claimed -Wno-unsafe-buffer-usage was needed only
for Doctest and that -Wno-missing-noreturn had "no way to silence...
otherwise" (PR #4871, which never actually attempted a source fix).
Neither held up under investigation (todo 130):
- -Wno-unsafe-buffer-usage is pervasive (208 distinct sites across 19
files measured with clang trunk in silkeh/clang:dev), spanning the
library's own low-level numeric/buffer code (to_chars, serializer,
lexer, binary reader/writer, input adapters, json_pointer) as well as
vendored Doctest itself (96 of the 208 sites). A source-level fix is
not feasible at this scale; the comment now says so instead of
blaming Doctest alone.
- -Wno-missing-noreturn had exactly two real trigger sites, both
genuinely and unconditionally non-returning: a test-only throwing
allocator (tests/src/unit-allocator.cpp) and, previously undiscovered,
wide_string_input_adapter::get_elements<T>() in
include/nlohmann/detail/input/input_adapters.hpp. Verified this isn't
a wider pattern by checking all 160 JSON_THROW call sites in the
library for functions whose entire body is an unconditional throw.
Annotated both ([[noreturn]] in the test file, since JSON_HEDLEY_NO_RETURN
is #undef'd by the time test code runs; JSON_HEDLEY_NO_RETURN in the
library file, its first real use anywhere in the codebase) and
dropped the suppression entirely.
single_include/nlohmann/json.hpp regenerated via `make amalgamate`;
`make check-amalgamation` passes.
Verified in Docker (silkeh/clang:dev, matching the ci_static_analysis_clang
CI job): baseline builds clean, and the full 194-target test suite builds
with zero warnings under the corrected CLANG_CXXFLAGS (-Wno-missing-noreturn
no longer in the list). Also sanity-compiled and ran unit-allocator.cpp and
unit-wstring.cpp on host Apple Clang to confirm behavior is unchanged.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix MSVC C4702 warning caused by JSON_HEDLEY_NO_RETURN on get_elements()
PR #5250 annotated wide_string_input_adapter::get_elements<T>() with
JSON_HEDLEY_NO_RETURN (it unconditionally throws). On MSVC this expands to
__declspec(noreturn), and MSVC correctly determined that the code following
its call in binary_reader.hpp is unreachable for that instantiation, firing
C4702 under /W4 /WX in the msvc, msvc-vs2026, and msvc-arm64 Debug jobs.
Clang doesn't flag this case, so the Docker verification for #5250 (which
only checked Clang -Weverything) didn't catch it.
This is the same warning class already tolerated for Release builds since
PR #5216, where MSVC's optimizer independently found the same dead code
after /Od was removed. Extend that existing /wd4702 suppression to Debug
builds too, instead of reverting the noreturn annotation.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>