Merge 140943b18e into 307c053b9b
This commit is contained in:
commit
9b3ef98ccf
@ -221,6 +221,16 @@ struct external_constructor<value_t::array>
|
|||||||
template<>
|
template<>
|
||||||
struct external_constructor<value_t::object>
|
struct external_constructor<value_t::object>
|
||||||
{
|
{
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
static void construct(BasicJsonType& j)
|
||||||
|
{
|
||||||
|
j.m_value.destroy(j.m_type);
|
||||||
|
j.m_type = value_t::object;
|
||||||
|
j.m_value.object = j.template create<typename BasicJsonType::object_t>();
|
||||||
|
j.set_parents();
|
||||||
|
j.assert_invariant();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
|
static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
|
||||||
{
|
{
|
||||||
@ -256,6 +266,28 @@ struct external_constructor<value_t::object>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// wrappers //
|
||||||
|
//////////////
|
||||||
|
|
||||||
|
template<typename ArrayType>
|
||||||
|
struct array_type_wrapper
|
||||||
|
{
|
||||||
|
const ArrayType& array;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ObjectType>
|
||||||
|
struct object_type_wrapper
|
||||||
|
{
|
||||||
|
const ObjectType& object;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename StringType>
|
||||||
|
struct string_type_wrapper
|
||||||
|
{
|
||||||
|
const StringType& string;
|
||||||
|
};
|
||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
// to_json //
|
// to_json //
|
||||||
/////////////
|
/////////////
|
||||||
@ -293,6 +325,17 @@ inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
|
|||||||
external_constructor<value_t::string>::construct(j, std::move(s));
|
external_constructor<value_t::string>::construct(j, std::move(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename StringType>
|
||||||
|
using string_type_constructible_from_data_and_size = decltype(typename BasicJsonType::string_t(
|
||||||
|
std::declval<const StringType&>().data(), std::declval<const StringType&>().size()));
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename StringType, detail::enable_if_t<
|
||||||
|
detail::is_detected<string_type_constructible_from_data_and_size, BasicJsonType, StringType>::value, int> = 0>
|
||||||
|
void to_json(BasicJsonType& j, detail::string_type_wrapper<StringType> s)
|
||||||
|
{
|
||||||
|
external_constructor<value_t::string>::construct(j, typename BasicJsonType::string_t(s.string.data(), s.string.size()));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename FloatType,
|
template<typename BasicJsonType, typename FloatType,
|
||||||
enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
|
enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
|
||||||
inline void to_json(BasicJsonType& j, FloatType val) noexcept
|
inline void to_json(BasicJsonType& j, FloatType val) noexcept
|
||||||
@ -343,6 +386,18 @@ inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
|
|||||||
external_constructor<value_t::array>::construct(j, arr);
|
external_constructor<value_t::array>::construct(j, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename ArrayType>
|
||||||
|
using array_type_constructible_from_iter = decltype(typename BasicJsonType::array_t(
|
||||||
|
std::declval<result_of_begin<const ArrayType&>>(), std::declval<result_of_end<const ArrayType&>>()));
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename ArrayType, detail::enable_if_t<
|
||||||
|
detail::is_detected<array_type_constructible_from_iter, BasicJsonType, ArrayType>::value, int> = 0>
|
||||||
|
void to_json(BasicJsonType& j, detail::array_type_wrapper<ArrayType> a)
|
||||||
|
{
|
||||||
|
external_constructor<value_t::array>::construct(j,
|
||||||
|
typename BasicJsonType::array_t(a.array.begin(), a.array.end()));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
|
inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
|
||||||
{
|
{
|
||||||
@ -375,6 +430,43 @@ inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
|||||||
external_constructor<value_t::object>::construct(j, std::move(obj));
|
external_constructor<value_t::object>::construct(j, std::move(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename BasicJsonType, typename ObjectType,
|
||||||
|
enable_if_t < is_compatible_object_type<BasicJsonType, ObjectType>::value
|
||||||
|
|| is_basic_json<ObjectType>::value, int > = 0 >
|
||||||
|
void to_json(BasicJsonType& j, const object_type_wrapper<ObjectType>& obj)
|
||||||
|
{
|
||||||
|
external_constructor<value_t::object>::construct(j, obj.object);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename ObjectType>
|
||||||
|
using object_type_key_constructible_from_data_and_size = decltype(
|
||||||
|
typename BasicJsonType::object_t::key_type(
|
||||||
|
std::declval<const typename ObjectType::key_type&>().data(),
|
||||||
|
std::declval<const typename ObjectType::key_type&>().size()));
|
||||||
|
|
||||||
|
template < typename BasicJsonType, typename ObjectType,
|
||||||
|
enable_if_t < !is_compatible_object_type<BasicJsonType, ObjectType>::value
|
||||||
|
&& !is_basic_json<ObjectType>::value
|
||||||
|
&& detail::is_detected<object_type_key_constructible_from_data_and_size,
|
||||||
|
BasicJsonType, ObjectType>::value, int > = 0 >
|
||||||
|
void to_json(BasicJsonType& j, const object_type_wrapper<ObjectType>& o)
|
||||||
|
{
|
||||||
|
using std::begin;
|
||||||
|
using std::end;
|
||||||
|
|
||||||
|
external_constructor<value_t::object>::construct(j);
|
||||||
|
|
||||||
|
auto& obj = j.template get_ref<typename BasicJsonType::object_t&>();
|
||||||
|
std::transform(begin(o.object), end(o.object), std::inserter(obj, obj.end()),
|
||||||
|
[](const typename ObjectType::value_type & val)
|
||||||
|
{
|
||||||
|
return typename BasicJsonType::object_t::value_type
|
||||||
|
{
|
||||||
|
typename BasicJsonType::object_t::key_type(val.first.data(), val.first.size()),
|
||||||
|
BasicJsonType(val.second)};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
typename BasicJsonType, typename T, std::size_t N,
|
typename BasicJsonType, typename T, std::size_t N,
|
||||||
enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
|
enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
|
||||||
|
|||||||
@ -833,12 +833,79 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
assert_invariant();
|
assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename BasicJsonType, class Serializer, typename SerializedType,
|
||||||
|
class WrapperType>
|
||||||
|
using serializer_has_to_json_with_type_wrapper = decltype(Serializer::to_json(
|
||||||
|
std::declval<BasicJsonType&>(), std::declval<const WrapperType&>()));
|
||||||
|
|
||||||
|
template <typename OtherStringType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
detail::is_detected<serializer_has_to_json_with_type_wrapper,
|
||||||
|
basic_json_t, JSONSerializer<OtherStringType>, OtherStringType,
|
||||||
|
detail::string_type_wrapper<OtherStringType>>::value, int > = 0 >
|
||||||
|
void other_string_to_json(const OtherStringType& str)
|
||||||
|
{
|
||||||
|
JSONSerializer<OtherStringType>::to_json(*this, detail::string_type_wrapper<OtherStringType> {str});
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename OtherStringType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
!detail::is_detected<serializer_has_to_json_with_type_wrapper,
|
||||||
|
basic_json_t, JSONSerializer<OtherStringType>, OtherStringType,
|
||||||
|
detail::string_type_wrapper<OtherStringType>>::value, int > = 0 >
|
||||||
|
void other_string_to_json(const OtherStringType& str)
|
||||||
|
{
|
||||||
|
JSONSerializer<OtherStringType>::to_json(*this, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OtherObjectType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
detail::is_detected<serializer_has_to_json_with_type_wrapper,
|
||||||
|
basic_json_t, JSONSerializer<OtherObjectType>, OtherObjectType,
|
||||||
|
detail::object_type_wrapper<OtherObjectType>>::value, int > = 0 >
|
||||||
|
void other_object_to_json(const OtherObjectType& obj)
|
||||||
|
{
|
||||||
|
JSONSerializer<OtherObjectType>::to_json(*this, detail::object_type_wrapper<OtherObjectType> {obj});
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename OtherObjectType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
!detail::is_detected<serializer_has_to_json_with_type_wrapper,
|
||||||
|
basic_json_t, JSONSerializer<OtherObjectType>, OtherObjectType,
|
||||||
|
detail::object_type_wrapper<OtherObjectType>>::value, int > = 0 >
|
||||||
|
void other_object_to_json(const OtherObjectType& obj)
|
||||||
|
{
|
||||||
|
JSONSerializer<OtherObjectType>::to_json(*this, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OtherArrayType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
detail::is_detected<serializer_has_to_json_with_type_wrapper,
|
||||||
|
basic_json_t, JSONSerializer<OtherArrayType>, OtherArrayType,
|
||||||
|
detail::array_type_wrapper<OtherArrayType>>::value, int > = 0 >
|
||||||
|
void other_array_to_json(const OtherArrayType& arr)
|
||||||
|
{
|
||||||
|
JSONSerializer<OtherArrayType>::to_json(*this, detail::array_type_wrapper<OtherArrayType> {arr});
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename OtherArrayType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
!detail::is_detected<serializer_has_to_json_with_type_wrapper,
|
||||||
|
basic_json_t, JSONSerializer<OtherArrayType>, OtherArrayType,
|
||||||
|
detail::array_type_wrapper<OtherArrayType>>::value, int > = 0 >
|
||||||
|
void other_array_to_json(const OtherArrayType& arr)
|
||||||
|
{
|
||||||
|
JSONSerializer<OtherArrayType>::to_json(*this, arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
/// @brief create a JSON value from an existing one
|
/// @brief create a JSON value from an existing one
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
||||||
template < typename BasicJsonType,
|
template < typename BasicJsonType,
|
||||||
detail::enable_if_t <
|
detail::enable_if_t <
|
||||||
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
|
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
|
||||||
basic_json(const BasicJsonType& val)
|
JSON_EXPLICIT basic_json(const BasicJsonType& val)
|
||||||
{
|
{
|
||||||
using other_boolean_t = typename BasicJsonType::boolean_t;
|
using other_boolean_t = typename BasicJsonType::boolean_t;
|
||||||
using other_number_float_t = typename BasicJsonType::number_float_t;
|
using other_number_float_t = typename BasicJsonType::number_float_t;
|
||||||
@ -864,13 +931,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
|
JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
|
||||||
break;
|
break;
|
||||||
case value_t::string:
|
case value_t::string:
|
||||||
JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
|
other_string_to_json(val.template get_ref<const other_string_t&>());
|
||||||
break;
|
break;
|
||||||
case value_t::object:
|
case value_t::object:
|
||||||
JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
|
other_object_to_json(val.template get_ref<const other_object_t&>());
|
||||||
break;
|
break;
|
||||||
case value_t::array:
|
case value_t::array:
|
||||||
JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
|
other_array_to_json(val.template get_ref<const other_array_t&>());
|
||||||
break;
|
break;
|
||||||
case value_t::binary:
|
case value_t::binary:
|
||||||
JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
|
JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
|
||||||
@ -1665,7 +1732,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
int > = 0 >
|
int > = 0 >
|
||||||
BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
|
BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
|
||||||
{
|
{
|
||||||
return *this;
|
return BasicJsonType(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@ -5531,6 +5531,16 @@ struct external_constructor<value_t::array>
|
|||||||
template<>
|
template<>
|
||||||
struct external_constructor<value_t::object>
|
struct external_constructor<value_t::object>
|
||||||
{
|
{
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
static void construct(BasicJsonType& j)
|
||||||
|
{
|
||||||
|
j.m_value.destroy(j.m_type);
|
||||||
|
j.m_type = value_t::object;
|
||||||
|
j.m_value.object = j.template create<typename BasicJsonType::object_t>();
|
||||||
|
j.set_parents();
|
||||||
|
j.assert_invariant();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
|
static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
|
||||||
{
|
{
|
||||||
@ -5566,6 +5576,28 @@ struct external_constructor<value_t::object>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// wrappers //
|
||||||
|
//////////////
|
||||||
|
|
||||||
|
template<typename ArrayType>
|
||||||
|
struct array_type_wrapper
|
||||||
|
{
|
||||||
|
const ArrayType& array;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ObjectType>
|
||||||
|
struct object_type_wrapper
|
||||||
|
{
|
||||||
|
const ObjectType& object;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename StringType>
|
||||||
|
struct string_type_wrapper
|
||||||
|
{
|
||||||
|
const StringType& string;
|
||||||
|
};
|
||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
// to_json //
|
// to_json //
|
||||||
/////////////
|
/////////////
|
||||||
@ -5603,6 +5635,17 @@ inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
|
|||||||
external_constructor<value_t::string>::construct(j, std::move(s));
|
external_constructor<value_t::string>::construct(j, std::move(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename StringType>
|
||||||
|
using string_type_constructible_from_data_and_size = decltype(typename BasicJsonType::string_t(
|
||||||
|
std::declval<const StringType&>().data(), std::declval<const StringType&>().size()));
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename StringType, detail::enable_if_t<
|
||||||
|
detail::is_detected<string_type_constructible_from_data_and_size, BasicJsonType, StringType>::value, int> = 0>
|
||||||
|
void to_json(BasicJsonType& j, detail::string_type_wrapper<StringType> s)
|
||||||
|
{
|
||||||
|
external_constructor<value_t::string>::construct(j, typename BasicJsonType::string_t(s.string.data(), s.string.size()));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename FloatType,
|
template<typename BasicJsonType, typename FloatType,
|
||||||
enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
|
enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
|
||||||
inline void to_json(BasicJsonType& j, FloatType val) noexcept
|
inline void to_json(BasicJsonType& j, FloatType val) noexcept
|
||||||
@ -5653,6 +5696,18 @@ inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
|
|||||||
external_constructor<value_t::array>::construct(j, arr);
|
external_constructor<value_t::array>::construct(j, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename ArrayType>
|
||||||
|
using array_type_constructible_from_iter = decltype(typename BasicJsonType::array_t(
|
||||||
|
std::declval<result_of_begin<const ArrayType&>>(), std::declval<result_of_end<const ArrayType&>>()));
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename ArrayType, detail::enable_if_t<
|
||||||
|
detail::is_detected<array_type_constructible_from_iter, BasicJsonType, ArrayType>::value, int> = 0>
|
||||||
|
void to_json(BasicJsonType& j, detail::array_type_wrapper<ArrayType> a)
|
||||||
|
{
|
||||||
|
external_constructor<value_t::array>::construct(j,
|
||||||
|
typename BasicJsonType::array_t(a.array.begin(), a.array.end()));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
|
inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
|
||||||
{
|
{
|
||||||
@ -5685,6 +5740,43 @@ inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
|
|||||||
external_constructor<value_t::object>::construct(j, std::move(obj));
|
external_constructor<value_t::object>::construct(j, std::move(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename BasicJsonType, typename ObjectType,
|
||||||
|
enable_if_t < is_compatible_object_type<BasicJsonType, ObjectType>::value
|
||||||
|
|| is_basic_json<ObjectType>::value, int > = 0 >
|
||||||
|
void to_json(BasicJsonType& j, const object_type_wrapper<ObjectType>& obj)
|
||||||
|
{
|
||||||
|
external_constructor<value_t::object>::construct(j, obj.object);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename BasicJsonType, typename ObjectType>
|
||||||
|
using object_type_key_constructible_from_data_and_size = decltype(
|
||||||
|
typename BasicJsonType::object_t::key_type(
|
||||||
|
std::declval<const typename ObjectType::key_type&>().data(),
|
||||||
|
std::declval<const typename ObjectType::key_type&>().size()));
|
||||||
|
|
||||||
|
template < typename BasicJsonType, typename ObjectType,
|
||||||
|
enable_if_t < !is_compatible_object_type<BasicJsonType, ObjectType>::value
|
||||||
|
&& !is_basic_json<ObjectType>::value
|
||||||
|
&& detail::is_detected<object_type_key_constructible_from_data_and_size,
|
||||||
|
BasicJsonType, ObjectType>::value, int > = 0 >
|
||||||
|
void to_json(BasicJsonType& j, const object_type_wrapper<ObjectType>& o)
|
||||||
|
{
|
||||||
|
using std::begin;
|
||||||
|
using std::end;
|
||||||
|
|
||||||
|
external_constructor<value_t::object>::construct(j);
|
||||||
|
|
||||||
|
auto& obj = j.template get_ref<typename BasicJsonType::object_t&>();
|
||||||
|
std::transform(begin(o.object), end(o.object), std::inserter(obj, obj.end()),
|
||||||
|
[](const typename ObjectType::value_type & val)
|
||||||
|
{
|
||||||
|
return typename BasicJsonType::object_t::value_type
|
||||||
|
{
|
||||||
|
typename BasicJsonType::object_t::key_type(val.first.data(), val.first.size()),
|
||||||
|
BasicJsonType(val.second)};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
typename BasicJsonType, typename T, std::size_t N,
|
typename BasicJsonType, typename T, std::size_t N,
|
||||||
enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
|
enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
|
||||||
@ -20049,12 +20141,79 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
assert_invariant();
|
assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename BasicJsonType, class Serializer, typename SerializedType,
|
||||||
|
class WrapperType>
|
||||||
|
using serializer_has_to_json_with_type_wrapper = decltype(Serializer::to_json(
|
||||||
|
std::declval<BasicJsonType&>(), std::declval<const WrapperType&>()));
|
||||||
|
|
||||||
|
template <typename OtherStringType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
detail::is_detected<serializer_has_to_json_with_type_wrapper,
|
||||||
|
basic_json_t, JSONSerializer<OtherStringType>, OtherStringType,
|
||||||
|
detail::string_type_wrapper<OtherStringType>>::value, int > = 0 >
|
||||||
|
void other_string_to_json(const OtherStringType& str)
|
||||||
|
{
|
||||||
|
JSONSerializer<OtherStringType>::to_json(*this, detail::string_type_wrapper<OtherStringType> {str});
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename OtherStringType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
!detail::is_detected<serializer_has_to_json_with_type_wrapper,
|
||||||
|
basic_json_t, JSONSerializer<OtherStringType>, OtherStringType,
|
||||||
|
detail::string_type_wrapper<OtherStringType>>::value, int > = 0 >
|
||||||
|
void other_string_to_json(const OtherStringType& str)
|
||||||
|
{
|
||||||
|
JSONSerializer<OtherStringType>::to_json(*this, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OtherObjectType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
detail::is_detected<serializer_has_to_json_with_type_wrapper,
|
||||||
|
basic_json_t, JSONSerializer<OtherObjectType>, OtherObjectType,
|
||||||
|
detail::object_type_wrapper<OtherObjectType>>::value, int > = 0 >
|
||||||
|
void other_object_to_json(const OtherObjectType& obj)
|
||||||
|
{
|
||||||
|
JSONSerializer<OtherObjectType>::to_json(*this, detail::object_type_wrapper<OtherObjectType> {obj});
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename OtherObjectType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
!detail::is_detected<serializer_has_to_json_with_type_wrapper,
|
||||||
|
basic_json_t, JSONSerializer<OtherObjectType>, OtherObjectType,
|
||||||
|
detail::object_type_wrapper<OtherObjectType>>::value, int > = 0 >
|
||||||
|
void other_object_to_json(const OtherObjectType& obj)
|
||||||
|
{
|
||||||
|
JSONSerializer<OtherObjectType>::to_json(*this, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OtherArrayType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
detail::is_detected<serializer_has_to_json_with_type_wrapper,
|
||||||
|
basic_json_t, JSONSerializer<OtherArrayType>, OtherArrayType,
|
||||||
|
detail::array_type_wrapper<OtherArrayType>>::value, int > = 0 >
|
||||||
|
void other_array_to_json(const OtherArrayType& arr)
|
||||||
|
{
|
||||||
|
JSONSerializer<OtherArrayType>::to_json(*this, detail::array_type_wrapper<OtherArrayType> {arr});
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename OtherArrayType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
!detail::is_detected<serializer_has_to_json_with_type_wrapper,
|
||||||
|
basic_json_t, JSONSerializer<OtherArrayType>, OtherArrayType,
|
||||||
|
detail::array_type_wrapper<OtherArrayType>>::value, int > = 0 >
|
||||||
|
void other_array_to_json(const OtherArrayType& arr)
|
||||||
|
{
|
||||||
|
JSONSerializer<OtherArrayType>::to_json(*this, arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
/// @brief create a JSON value from an existing one
|
/// @brief create a JSON value from an existing one
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
||||||
template < typename BasicJsonType,
|
template < typename BasicJsonType,
|
||||||
detail::enable_if_t <
|
detail::enable_if_t <
|
||||||
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
|
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
|
||||||
basic_json(const BasicJsonType& val)
|
JSON_EXPLICIT basic_json(const BasicJsonType& val)
|
||||||
{
|
{
|
||||||
using other_boolean_t = typename BasicJsonType::boolean_t;
|
using other_boolean_t = typename BasicJsonType::boolean_t;
|
||||||
using other_number_float_t = typename BasicJsonType::number_float_t;
|
using other_number_float_t = typename BasicJsonType::number_float_t;
|
||||||
@ -20080,13 +20239,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
|
JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
|
||||||
break;
|
break;
|
||||||
case value_t::string:
|
case value_t::string:
|
||||||
JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
|
other_string_to_json(val.template get_ref<const other_string_t&>());
|
||||||
break;
|
break;
|
||||||
case value_t::object:
|
case value_t::object:
|
||||||
JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
|
other_object_to_json(val.template get_ref<const other_object_t&>());
|
||||||
break;
|
break;
|
||||||
case value_t::array:
|
case value_t::array:
|
||||||
JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
|
other_array_to_json(val.template get_ref<const other_array_t&>());
|
||||||
break;
|
break;
|
||||||
case value_t::binary:
|
case value_t::binary:
|
||||||
JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
|
JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
|
||||||
@ -20881,7 +21040,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
int > = 0 >
|
int > = 0 >
|
||||||
BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
|
BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
|
||||||
{
|
{
|
||||||
return *this;
|
return BasicJsonType(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@ -10,7 +10,9 @@
|
|||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
using nlohmann::json;
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@ -308,17 +310,144 @@ TEST_CASE("alternative string type")
|
|||||||
|
|
||||||
SECTION("JSON pointer")
|
SECTION("JSON pointer")
|
||||||
{
|
{
|
||||||
// conversion from json to alt_json fails to compile (see #3425);
|
|
||||||
// attempted fix(*) produces: [[['b','a','r'],['b','a','z']]] (with each char being an integer)
|
|
||||||
// (*) disable implicit conversion for json_refs of any basic_json type
|
|
||||||
// alt_json j = R"(
|
|
||||||
// {
|
|
||||||
// "foo": ["bar", "baz"]
|
|
||||||
// }
|
|
||||||
// )"_json;
|
|
||||||
auto j = alt_json::parse(R"({"foo": ["bar", "baz"]})");
|
auto j = alt_json::parse(R"({"foo": ["bar", "baz"]})");
|
||||||
|
|
||||||
CHECK(j.at(alt_json::json_pointer("/foo/0")) == j["foo"][0]);
|
CHECK(j.at(alt_json::json_pointer("/foo/0")) == j["foo"][0]);
|
||||||
CHECK(j.at(alt_json::json_pointer("/foo/1")) == j["foo"][1]);
|
CHECK(j.at(alt_json::json_pointer("/foo/1")) == j["foo"][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("conversion (#3425)")
|
||||||
|
{
|
||||||
|
SECTION("string")
|
||||||
|
{
|
||||||
|
SECTION("json to alt_json")
|
||||||
|
{
|
||||||
|
json j("foo");
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
|
alt_json aj = j;
|
||||||
|
#else
|
||||||
|
alt_json aj = alt_json(j);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
alt_string as = aj.dump();
|
||||||
|
CHECK(j.is_string());
|
||||||
|
CHECK(j.dump() == "\"foo\"");
|
||||||
|
CHECK(j.dump() == std::string(as.data(), as.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("alt_json to json")
|
||||||
|
{
|
||||||
|
alt_json aj("foo");
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
|
json j = aj;
|
||||||
|
#else
|
||||||
|
json j = json(aj);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
alt_string as = aj.dump();
|
||||||
|
CHECK(aj.is_string());
|
||||||
|
CHECK(j.dump() == "\"foo\"");
|
||||||
|
CHECK(j.dump() == std::string(as.data(), as.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("array")
|
||||||
|
{
|
||||||
|
SECTION("json to alt_json")
|
||||||
|
{
|
||||||
|
json j{"foo"};
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
|
alt_json aj = j;
|
||||||
|
#else
|
||||||
|
alt_json aj = alt_json(j);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
alt_string as = aj.dump();
|
||||||
|
CHECK(j.is_array());
|
||||||
|
CHECK(j.dump() == "[\"foo\"]");
|
||||||
|
CHECK(j.dump() == std::string(as.data(), as.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("alt_json to json")
|
||||||
|
{
|
||||||
|
alt_json aj{"foo"};
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
|
json j = aj;
|
||||||
|
#else
|
||||||
|
json j = json(aj);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
alt_string as = aj.dump();
|
||||||
|
CHECK(aj.is_array());
|
||||||
|
CHECK(j.dump() == "[\"foo\"]");
|
||||||
|
CHECK(j.dump() == std::string(as.data(), as.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("object")
|
||||||
|
{
|
||||||
|
SECTION("json to alt_json")
|
||||||
|
{
|
||||||
|
json j{{"foo", {"bar", "baz"}}};
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
|
alt_json aj = j;
|
||||||
|
#else
|
||||||
|
alt_json aj = alt_json(j);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
alt_string as = aj.dump();
|
||||||
|
CHECK(j.is_object());
|
||||||
|
CHECK(j.dump() == "{\"foo\":[\"bar\",\"baz\"]}");
|
||||||
|
CHECK(j.dump() == std::string(as.data(), as.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("alt_json to json")
|
||||||
|
{
|
||||||
|
alt_json aj{{"foo", {"bar", "baz"}}};
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
|
json j = aj;
|
||||||
|
#else
|
||||||
|
json j = json(aj);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
alt_string as = aj.dump();
|
||||||
|
CHECK(aj.is_object());
|
||||||
|
CHECK(j.dump() == "{\"foo\":[\"bar\",\"baz\"]}");
|
||||||
|
CHECK(j.dump() == std::string(as.data(), as.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("binary")
|
||||||
|
{
|
||||||
|
SECTION("json to alt_json")
|
||||||
|
{
|
||||||
|
auto j = json::binary({1, 2, 3, 4}, 128);
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
|
alt_json aj = j;
|
||||||
|
#else
|
||||||
|
alt_json aj = alt_json(j);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
alt_string as = aj.dump();
|
||||||
|
CHECK(j.is_binary());
|
||||||
|
CHECK(j.dump() == "{\"bytes\":[1,2,3,4],\"subtype\":128}");
|
||||||
|
CHECK(j.dump() == std::string(as.data(), as.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("alt_json to json")
|
||||||
|
{
|
||||||
|
auto aj = alt_json::binary({1, 2, 3, 4}, 128);
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
|
json j = aj;
|
||||||
|
#else
|
||||||
|
json j = json(aj);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
alt_string as = aj.dump();
|
||||||
|
CHECK(aj.is_binary());
|
||||||
|
CHECK(j.dump() == "{\"bytes\":[1,2,3,4],\"subtype\":128}");
|
||||||
|
CHECK(j.dump() == std::string(as.data(), as.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1467,7 +1467,11 @@ TEST_CASE("regression tests 1")
|
|||||||
|
|
||||||
SECTION("issue #972 - Segmentation fault on G++ when trying to assign json string literal to custom json type")
|
SECTION("issue #972 - Segmentation fault on G++ when trying to assign json string literal to custom json type")
|
||||||
{
|
{
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
my_json foo = R"([1, 2, 3])"_json;
|
my_json foo = R"([1, 2, 3])"_json;
|
||||||
|
#else
|
||||||
|
my_json foo = my_json(R"([1, 2, 3])"_json);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #977 - Assigning between different json types")
|
SECTION("issue #977 - Assigning between different json types")
|
||||||
@ -1478,7 +1482,11 @@ TEST_CASE("regression tests 1")
|
|||||||
CHECK(lj.size() == 1);
|
CHECK(lj.size() == 1);
|
||||||
CHECK(lj["x"] == 3);
|
CHECK(lj["x"] == 3);
|
||||||
CHECK(ff.x == 3);
|
CHECK(ff.x == 3);
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
nlohmann::json nj = lj; // This line works as expected
|
nlohmann::json nj = lj; // This line works as expected
|
||||||
|
#else
|
||||||
|
nlohmann::json nj = nlohmann::json(lj); // This line works as expected
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -792,12 +792,12 @@ TEST_CASE("regression tests 2")
|
|||||||
CHECK(test1.dump() == "{\"root\":{}}");
|
CHECK(test1.dump() == "{\"root\":{}}");
|
||||||
|
|
||||||
ordered_json test2;
|
ordered_json test2;
|
||||||
test2[ordered_json::json_pointer(p)] = json::object();
|
test2[ordered_json::json_pointer(p)] = ordered_json::object();
|
||||||
CHECK(test2.dump() == "{\"root\":{}}");
|
CHECK(test2.dump() == "{\"root\":{}}");
|
||||||
|
|
||||||
// json::json_pointer and ordered_json::json_pointer are the same type; behave as above
|
// json::json_pointer and ordered_json::json_pointer are the same type; behave as above
|
||||||
ordered_json test3;
|
ordered_json test3;
|
||||||
test3[json::json_pointer(p)] = json::object();
|
test3[json::json_pointer(p)] = ordered_json::object();
|
||||||
CHECK(std::is_same<json::json_pointer::string_t, ordered_json::json_pointer::string_t>::value);
|
CHECK(std::is_same<json::json_pointer::string_t, ordered_json::json_pointer::string_t>::value);
|
||||||
CHECK(test3.dump() == "{\"root\":{}}");
|
CHECK(test3.dump() == "{\"root\":{}}");
|
||||||
}
|
}
|
||||||
@ -877,7 +877,8 @@ TEST_CASE("regression tests 2")
|
|||||||
CHECK(td.str == "value");
|
CHECK(td.str == "value");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_20
|
// this is no longer supported when implicit conversions are disabled
|
||||||
|
#if defined(JSON_HAS_CPP_20) && JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
SECTION("issue #3312 - Parse to custom class from unordered_json breaks on G++11.2.0 with C++20")
|
SECTION("issue #3312 - Parse to custom class from unordered_json breaks on G++11.2.0 with C++20")
|
||||||
{
|
{
|
||||||
// see test for #3171
|
// see test for #3171
|
||||||
|
|||||||
@ -695,14 +695,22 @@ TEST_CASE("different basic_json types conversions")
|
|||||||
SECTION("null")
|
SECTION("null")
|
||||||
{
|
{
|
||||||
json j;
|
json j;
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
custom_json cj = j;
|
custom_json cj = j;
|
||||||
|
#else
|
||||||
|
custom_json cj = custom_json(j);
|
||||||
|
#endif
|
||||||
CHECK(cj == nullptr);
|
CHECK(cj == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("boolean")
|
SECTION("boolean")
|
||||||
{
|
{
|
||||||
json j = true;
|
json j = true;
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
custom_json cj = j;
|
custom_json cj = j;
|
||||||
|
#else
|
||||||
|
custom_json cj = custom_json(j);
|
||||||
|
#endif
|
||||||
CHECK(cj == true);
|
CHECK(cj == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,49 +718,77 @@ TEST_CASE("different basic_json types conversions")
|
|||||||
{
|
{
|
||||||
json j(json::value_t::discarded);
|
json j(json::value_t::discarded);
|
||||||
custom_json cj;
|
custom_json cj;
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
CHECK_NOTHROW(cj = j);
|
CHECK_NOTHROW(cj = j);
|
||||||
|
#else
|
||||||
|
CHECK_NOTHROW(cj = custom_json(j));
|
||||||
|
#endif
|
||||||
CHECK(cj.type() == custom_json::value_t::discarded);
|
CHECK(cj.type() == custom_json::value_t::discarded);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("array")
|
SECTION("array")
|
||||||
{
|
{
|
||||||
json j = {1, 2, 3};
|
json j = {1, 2, 3};
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
custom_json cj = j;
|
custom_json cj = j;
|
||||||
|
#else
|
||||||
|
custom_json cj = custom_json(j);
|
||||||
|
#endif
|
||||||
CHECK((cj == std::vector<int> {1, 2, 3}));
|
CHECK((cj == std::vector<int> {1, 2, 3}));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("integer")
|
SECTION("integer")
|
||||||
{
|
{
|
||||||
json j = 42;
|
json j = 42;
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
custom_json cj = j;
|
custom_json cj = j;
|
||||||
|
#else
|
||||||
|
custom_json cj = custom_json(j);
|
||||||
|
#endif
|
||||||
CHECK(cj == 42);
|
CHECK(cj == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("float")
|
SECTION("float")
|
||||||
{
|
{
|
||||||
json j = 42.0;
|
json j = 42.0;
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
custom_json cj = j;
|
custom_json cj = j;
|
||||||
|
#else
|
||||||
|
custom_json cj = custom_json(j);
|
||||||
|
#endif
|
||||||
CHECK(cj == 42.0);
|
CHECK(cj == 42.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("unsigned")
|
SECTION("unsigned")
|
||||||
{
|
{
|
||||||
json j = 42u;
|
json j = 42u;
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
custom_json cj = j;
|
custom_json cj = j;
|
||||||
|
#else
|
||||||
|
custom_json cj = custom_json(j);
|
||||||
|
#endif
|
||||||
CHECK(cj == 42u);
|
CHECK(cj == 42u);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("string")
|
SECTION("string")
|
||||||
{
|
{
|
||||||
json j = "forty-two";
|
json j = "forty-two";
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
custom_json cj = j;
|
custom_json cj = j;
|
||||||
|
#else
|
||||||
|
custom_json cj = custom_json(j);
|
||||||
|
#endif
|
||||||
CHECK(cj == "forty-two");
|
CHECK(cj == "forty-two");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("binary")
|
SECTION("binary")
|
||||||
{
|
{
|
||||||
json j = json::binary({1, 2, 3}, 42);
|
json j = json::binary({1, 2, 3}, 42);
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
custom_json cj = j;
|
custom_json cj = j;
|
||||||
|
#else
|
||||||
|
custom_json cj = custom_json(j);
|
||||||
|
#endif
|
||||||
CHECK(cj.get_binary().subtype() == 42);
|
CHECK(cj.get_binary().subtype() == 42);
|
||||||
std::vector<std::uint8_t> cv = cj.get_binary();
|
std::vector<std::uint8_t> cv = cj.get_binary();
|
||||||
std::vector<std::uint8_t> v = j.get_binary();
|
std::vector<std::uint8_t> v = j.get_binary();
|
||||||
@ -762,7 +798,11 @@ TEST_CASE("different basic_json types conversions")
|
|||||||
SECTION("object")
|
SECTION("object")
|
||||||
{
|
{
|
||||||
json j = {{"forty", "two"}};
|
json j = {{"forty", "two"}};
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
custom_json cj = j;
|
custom_json cj = j;
|
||||||
|
#else
|
||||||
|
custom_json cj = custom_json(j);
|
||||||
|
#endif
|
||||||
auto m = j.get<std::map<std::string, std::string>>();
|
auto m = j.get<std::map<std::string, std::string>>();
|
||||||
CHECK(cj == m);
|
CHECK(cj == m);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user