Files
json/tests/src/unit-constructor2.cpp
T
Niels Lohmann 4d46bce4e1 Fix CI on develop (#5750)
* Fix CI configuration broken by recent merges and tool updates

- gcc_flags.cmake: drop -Wexperimental-fmv-target, which GCC 16 accepts
  only on aarch64; amd64 rejects it, so every GCC job failed while
  checking the compiler.
- ci_get_cmake: add VERBATIM so the checksum pipeline is passed to the
  shell intact (the unescaped `$'` broke the generated Makefile and
  build.ninja, failing ci_cmake_flags and ci_module_cpp20); match the
  SHA-256 entry case-insensitively, as CMake 3.5.0 lists the archive as
  "Linux-x86_64"; and unpack with --strip-components, as that archive's
  top-level directory is spelled "Linux" too.
- ci_single_binaries: compile json.hpp's TU without IWYU's --error, as
  the comment above the gate already intends.
- tests: restore -Wno-deprecated-declarations for all non-MSVC compilers
  (#5737 kept it for GCC only), as several tests call deprecated
  functions on purpose; include thirdparty/fifo_map as SYSTEM.
- .clang-tidy: set misc-use-internal-linkage.AnalyzeTypes to false;
  clang-tidy 22.1 extended the check to classes and enums and flagged
  100 test helper types.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Fix library warnings and a JSON_DIAGNOSTICS parent bug

- binary_reader: pass integers to sax->number_integer() through
  conditional_static_cast<number_integer_t>, making the existing
  narrowing for a narrow number_integer_t explicit (MSVC C4244 and GCC
  -Wconversion/-Warith-conversion with the int16_t test from #5694);
  mark two Infer DEAD_STORE false positives with @infer-ignore.
- to_json: set the parents of an array built from a C++20 range view
  after all elements are in place; a reallocating push_back moved the
  earlier elements and left their parent pointers stale, failing the
  JSON_DIAGNOSTICS invariant assertion.
- json.hpp: suppress MSVC C4127 for the new is_ordered_map check in
  diff(), like the three existing ones; spell out std::formatter::parse's
  return and iterator types for clang-tidy 22.1.
- number_parse: make the Eisel-Lemire digit counter unsigned
  (GCC -Wstrict-overflow).
- string_utils: take encode_utf8's callable by const reference
  (cppcoreguidelines-missing-std-forward) and drop a \u from its doc
  comment (-Wdocumentation-unknown-command).
- ordered_map: include <memory> for std::allocator (cpplint).

Ran make amalgamate.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Fix tests failing in CI on develop

- unit-allocator: skip the #5640 test under MSVC STL iterator debugging,
  where containers allocate a debug proxy in noexcept move constructors
  and a failing allocation terminates; move a decrement out of an if
  condition (bugprone-inc-dec-in-conditions).
- unit-conversions: expect the "(/0)" path with JSON_DIAGNOSTICS;
  compare strict enums via get<>() rather than through the noexcept
  operator==(ScalarType, json), which bugprone-exception-escape flags.
- unit-alt-string: suppress -Wexit-time-destructors for the strict enum
  macro and misc-use-internal-linkage for its enum.
- unit-bjdata: call the static lookup functions through the type and
  pass unsigned char (-Wsign-conversion on amd64).
- Mark Infer false positives with @infer-ignore in unit-diagnostics,
  unit-pointer_access, unit-udt, and unit-conversions.
- Smaller clang-tidy 22.1 findings in unit-class_parser,
  unit-constructor2, unit-custom-base-class, unit-locale-cpp, and
  unit-noexcept.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-02 11:23:55 +02:00

187 lines
4.7 KiB
C++

// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++ (supporting code)
// | | |__ | | | | | | version 3.12.0
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#include "doctest_compatibility.h"
#include <nlohmann/json.hpp>
using nlohmann::json;
TEST_CASE("other constructors and destructor")
{
SECTION("copy constructor")
{
SECTION("object")
{
const json j {{"foo", 1}, {"bar", false}};
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("array")
{
const json j {"foo", 1, 42.23, false};
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("null")
{
const json j(nullptr);
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("boolean")
{
const json j(true);
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("string")
{
const json j("Hello world");
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("number (integer)")
{
const json j(42);
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("number (unsigned)")
{
const json j(42u);
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("number (floating-point)")
{
const json j(42.23);
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
SECTION("binary")
{
const json j = json::binary({1, 2, 3});
json k(j); // NOLINT(performance-unnecessary-copy-initialization)
CHECK(j == k);
}
}
SECTION("move constructor")
{
json j {{"foo", "bar"}, {"baz", {1, 2, 3, 4}}, {"a", 42u}, {"b", 42.23}, {"c", nullptr}};
CHECK(j.type() == json::value_t::object);
const json k(std::move(j));
CHECK(k.type() == json::value_t::object);
CHECK(j.type() == json::value_t::null); // NOLINT(bugprone-use-after-move,hicpp-invalid-access-moved,clang-analyzer-cplusplus.Move) access after move is OK here
}
SECTION("copy assignment")
{
SECTION("object")
{
const json j {{"foo", 1}, {"bar", false}};
json k;
k = j;
CHECK(j == k);
}
SECTION("array")
{
const json j {"foo", 1, 42.23, false};
json k;
k = j;
CHECK(j == k);
}
SECTION("null")
{
const json j(nullptr);
json k;
k = j;
CHECK(j == k);
}
SECTION("boolean")
{
const json j(true);
json k;
k = j;
CHECK(j == k);
}
SECTION("string")
{
const json j("Hello world");
json k;
k = j;
CHECK(j == k);
}
SECTION("number (integer)")
{
const json j(42);
json k;
k = j;
CHECK(j == k);
}
SECTION("number (unsigned)")
{
const json j(42u);
json k;
k = j;
CHECK(j == k);
}
SECTION("number (floating-point)")
{
const json j(42.23);
json k;
k = j;
CHECK(j == k);
}
SECTION("binary")
{
const json j = json::binary({1, 2, 3});
json k;
k = j;
CHECK(j == k);
}
}
SECTION("destructor")
{
SECTION("object")
{
auto* j = new json {{"foo", 1}, {"bar", false}}; // NOLINT(cppcoreguidelines-owning-memory)
delete j; // NOLINT(cppcoreguidelines-owning-memory)
}
SECTION("array")
{
auto* j = new json {"foo", 1, 1u, false, 23.42}; // NOLINT(cppcoreguidelines-owning-memory)
delete j; // NOLINT(cppcoreguidelines-owning-memory)
}
SECTION("string")
{
auto* j = new json("Hello world"); // NOLINT(cppcoreguidelines-owning-memory)
delete j; // NOLINT(cppcoreguidelines-owning-memory)
}
}
}