mirror of
https://github.com/nlohmann/json.git
synced 2026-10-04 21:50:33 +00:00
Keep the serializer conversion for objects whose keys cannot be converted
#5591 added a test converting nlohmann::json into a basic_json whose string type cannot be constructed from std::string. That instantiates convert_iteratively(), whose members.emplace_back(next.key(), ...) needs exactly that key conversion, and broke the build of unit-alt-string. Dispatch on the key's constructibility and leave such conversions to the serializers, as the levels above the nesting bound already do (#3425). Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
+30
-13
@@ -1441,7 +1441,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
be destroyed.
|
||||
*/
|
||||
template<typename BasicJsonType>
|
||||
void convert_iteratively(const BasicJsonType& val)
|
||||
void convert_iteratively(const BasicJsonType& val, std::true_type /*unused*/)
|
||||
{
|
||||
using other_const_iterator = typename BasicJsonType::const_iterator;
|
||||
|
||||
@@ -1535,21 +1535,38 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
if (JSON_HEDLEY_LIKELY(guard.okay()))
|
||||
{
|
||||
// every element comes back to the converting constructor
|
||||
if (val.is_object())
|
||||
{
|
||||
using other_object_t = typename BasicJsonType::object_t;
|
||||
JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
|
||||
}
|
||||
else
|
||||
{
|
||||
using other_array_t = typename BasicJsonType::array_t;
|
||||
JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
|
||||
}
|
||||
convert_by_serializers(val);
|
||||
return;
|
||||
}
|
||||
|
||||
convert_iteratively(val);
|
||||
// the iterative conversion needs to construct this object type's keys
|
||||
// from those of @a val; if it cannot, neither can the range constructor,
|
||||
// and the serializers convert @a val some other way (see #3425)
|
||||
convert_iteratively(val, std::is_constructible<typename object_t::key_type, const typename BasicJsonType::string_t&> {});
|
||||
}
|
||||
|
||||
/// @brief convert the object or array @a val with the serializers; every
|
||||
/// element comes back to the converting constructor
|
||||
template<typename BasicJsonType>
|
||||
void convert_by_serializers(const BasicJsonType& val)
|
||||
{
|
||||
if (val.is_object())
|
||||
{
|
||||
using other_object_t = typename BasicJsonType::object_t;
|
||||
JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
|
||||
}
|
||||
else
|
||||
{
|
||||
using other_array_t = typename BasicJsonType::array_t;
|
||||
JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief convert @a val whose keys cannot be converted, see @ref convert_structured
|
||||
template<typename BasicJsonType>
|
||||
void convert_iteratively(const BasicJsonType& val, std::false_type /*unused*/)
|
||||
{
|
||||
convert_by_serializers(val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user