From aa3fadd4add137ed82015238a017b2905e595d2e Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 16 Sep 2026 08:24:32 +0200 Subject: [PATCH] Fix CI: build custom array types without a fill constructor, re-amalgamate copy_array_level() built the destination array with the fill constructor array_t(count, value), which is not part of the array container interface the library otherwise assumes (e.g. custom ArrayTypes that only provide a default and an iterator-pair constructor, as covered by unit-custom-array-type.cpp). Default- construct the array and resize() it instead, matching how the rest of the codebase already grows array_t. Also re-run the amalgamation, which had fallen out of sync with include/nlohmann/json.hpp. Signed-off-by: Niels Lohmann Co-Authored-By: Claude Sonnet 5 --- include/nlohmann/json.hpp | 8 +- single_include/nlohmann/json.hpp | 130 ++++++++++++++++--------------- 2 files changed, 73 insertions(+), 65 deletions(-) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 2ebf6910b..a565fb465 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -1078,8 +1078,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const array_t& src_array = *src.m_data.m_value.array; // create all elements up front: growing the array afterwards could - // invalidate the pointers that are handed to the worklist - dst.m_data.m_value.array = create(src_array.size(), basic_json()); + // invalidate the pointers that are handed to the worklist; resize() + // rather than the fill constructor, because not every array type + // provides the latter (e.g., ones without a matching allocator-aware + // fill constructor) + dst.m_data.m_value.array = create(); + dst.m_data.m_value.array->resize(src_array.size()); auto dst_it = dst.m_data.m_value.array->begin(); for (auto src_it = src_array.cbegin(); src_it != src_array.cend(); ++src_it, ++dst_it) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index cf6251e2d..1d7367433 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3833,71 +3833,71 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ -#define INCLUDE_NLOHMANN_JSON_FWD_HPP_ + #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ -#include // int64_t, uint64_t -#include // map -#include // allocator -#include // string -#include // vector + #include // int64_t, uint64_t + #include // map + #include // allocator + #include // string + #include // vector -// #include + // #include -/*! -@brief namespace for Niels Lohmann -@see https://github.com/nlohmann -@since version 1.0.0 -*/ -NLOHMANN_JSON_NAMESPACE_BEGIN + /*! + @brief namespace for Niels Lohmann + @see https://github.com/nlohmann + @since version 1.0.0 + */ + NLOHMANN_JSON_NAMESPACE_BEGIN -/*! -@brief default JSONSerializer template argument + /*! + @brief default JSONSerializer template argument -This serializer ignores the template arguments and uses ADL -([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) -for serialization. -*/ -template -struct adl_serializer; + This serializer ignores the template arguments and uses ADL + ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) + for serialization. + */ + template + struct adl_serializer; -/// a class to store JSON values -/// @sa https://json.nlohmann.me/api/basic_json/ -template class ObjectType = - std::map, - template class ArrayType = std::vector, - class StringType = std::string, class BooleanType = bool, - class NumberIntegerType = std::int64_t, - class NumberUnsignedType = std::uint64_t, - class NumberFloatType = double, - template class AllocatorType = std::allocator, - template class JSONSerializer = - adl_serializer, - class BinaryType = std::vector, // cppcheck-suppress syntaxError - class CustomBaseClass = void> -class basic_json; + /// a class to store JSON values + /// @sa https://json.nlohmann.me/api/basic_json/ + template class ObjectType = + std::map, + template class ArrayType = std::vector, + class StringType = std::string, class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = + adl_serializer, + class BinaryType = std::vector, // cppcheck-suppress syntaxError + class CustomBaseClass = void> + class basic_json; -/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document -/// @sa https://json.nlohmann.me/api/json_pointer/ -template -class json_pointer; + /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document + /// @sa https://json.nlohmann.me/api/json_pointer/ + template + class json_pointer; -/*! -@brief default specialization -@sa https://json.nlohmann.me/api/json/ -*/ -using json = basic_json<>; + /*! + @brief default specialization + @sa https://json.nlohmann.me/api/json/ + */ + using json = basic_json<>; -/// @brief a minimal map-like container that preserves insertion order -/// @sa https://json.nlohmann.me/api/ordered_map/ -template -struct ordered_map; + /// @brief a minimal map-like container that preserves insertion order + /// @sa https://json.nlohmann.me/api/ordered_map/ + template + struct ordered_map; -/// @brief specialization that maintains the insertion order of object keys -/// @sa https://json.nlohmann.me/api/ordered_json/ -using ordered_json = basic_json; + /// @brief specialization that maintains the insertion order of object keys + /// @sa https://json.nlohmann.me/api/ordered_json/ + using ordered_json = basic_json; -NLOHMANN_JSON_NAMESPACE_END + NLOHMANN_JSON_NAMESPACE_END #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ @@ -6016,7 +6016,7 @@ NLOHMANN_JSON_NAMESPACE_END // #include - // JSON_HAS_CPP_17 +// JSON_HAS_CPP_17 #ifdef JSON_HAS_CPP_17 #include // optional #endif @@ -24080,10 +24080,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const bool ignore_comments = false, const bool ignore_trailing_commas = false, const bool discard_number_values = false - ) + ) { return ::nlohmann::detail::parser(std::move(adapter), - std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas, discard_number_values); + std::move(cb), allow_exceptions, ignore_comments, ignore_trailing_commas, discard_number_values); } private: @@ -24992,8 +24992,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const array_t& src_array = *src.m_data.m_value.array; // create all elements up front: growing the array afterwards could - // invalidate the pointers that are handed to the worklist - dst.m_data.m_value.array = create(src_array.size(), basic_json()); + // invalidate the pointers that are handed to the worklist; resize() + // rather than the fill constructor, because not every array type + // provides the latter (e.g., ones without a matching allocator-aware + // fill constructor) + dst.m_data.m_value.array = create(); + dst.m_data.m_value.array->resize(src_array.size()); auto dst_it = dst.m_data.m_value.array->begin(); for (auto src_it = src_array.cbegin(); src_it != src_array.cend(); ++src_it, ++dst_it) @@ -25189,8 +25193,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec detail::enable_if_t < !detail::is_basic_json::value && detail::is_compatible_type::value, int > = 0 > basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape) - JSONSerializer::to_json(std::declval(), - std::forward(val)))) + JSONSerializer::to_json(std::declval(), + std::forward(val)))) { JSONSerializer::to_json(*this, std::forward(val)); set_parents(); @@ -25967,7 +25971,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec detail::has_from_json::value, int > = 0 > ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept( - JSONSerializer::from_json(std::declval(), std::declval()))) + JSONSerializer::from_json(std::declval(), std::declval()))) { auto ret = ValueType(); JSONSerializer::from_json(*this, ret); @@ -26009,7 +26013,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec detail::has_non_default_from_json::value, int > = 0 > ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept( - JSONSerializer::from_json(std::declval()))) + JSONSerializer::from_json(std::declval()))) { return JSONSerializer::from_json(*this); } @@ -26159,7 +26163,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec detail::has_from_json::value, int > = 0 > ValueType & get_to(ValueType& v) const noexcept(noexcept( - JSONSerializer::from_json(std::declval(), v))) + JSONSerializer::from_json(std::declval(), v))) { JSONSerializer::from_json(*this, v); return v;