mirror of
https://github.com/nlohmann/json.git
synced 2026-09-06 16:27:59 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50e392ab1a | ||
|
|
d2c2db92a9 |
@@ -1647,6 +1647,20 @@ class binary_writer
|
||||
return 'D'; // float 64
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief checks whether a JSON number fits into @a TargetType
|
||||
@param[in] el a JSON number of either the signed or unsigned integer kind
|
||||
@return whether @a el's value can be represented by @a TargetType without
|
||||
wrapping, regardless of which of the two kinds it is stored as
|
||||
*/
|
||||
template<typename TargetType>
|
||||
static bool bjdata_ndarray_value_in_range(const BasicJsonType& el)
|
||||
{
|
||||
return el.is_number_unsigned()
|
||||
? value_in_range_of<TargetType>(el.template get<std::uint64_t>())
|
||||
: value_in_range_of<TargetType>(el.template get<std::int64_t>());
|
||||
}
|
||||
|
||||
/*!
|
||||
@return false if the object is successfully converted to a bjdata ndarray, true if the type or size is invalid
|
||||
*/
|
||||
@@ -1667,6 +1681,16 @@ class binary_writer
|
||||
}
|
||||
CharType dtype = it->second;
|
||||
|
||||
// the 'B' (byte) marker is only defined by BJData Draft 3; emitting it
|
||||
// under the default Draft 2 mode would produce a stream that Draft 2
|
||||
// readers reject, so such an object falls back to a plain object
|
||||
// encoding instead (see the "Binary values" section of the BJData
|
||||
// documentation)
|
||||
if (dtype == 'B' && bjdata_version != bjdata_version_t::draft3)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
key = "_ArraySize_";
|
||||
// the dimensions are written verbatim as the header length below, so a
|
||||
// value that is not an array cannot produce a valid one: null emits 'Z'
|
||||
@@ -1731,6 +1755,60 @@ class binary_writer
|
||||
}
|
||||
}
|
||||
|
||||
// every element is cast to the (possibly narrower) C++ type matching
|
||||
// dtype below; a value that does not fit that type would silently
|
||||
// wrap (integers) or overflow to infinity (the "single" precision
|
||||
// float) instead of being reported, so such an object falls back to
|
||||
// a plain object encoding as well
|
||||
for (const auto& el : value.at(key))
|
||||
{
|
||||
bool in_range = true;
|
||||
switch (dtype)
|
||||
{
|
||||
case 'U':
|
||||
case 'C':
|
||||
case 'B':
|
||||
in_range = bjdata_ndarray_value_in_range<std::uint8_t>(el);
|
||||
break;
|
||||
case 'i':
|
||||
in_range = bjdata_ndarray_value_in_range<std::int8_t>(el);
|
||||
break;
|
||||
case 'u':
|
||||
in_range = bjdata_ndarray_value_in_range<std::uint16_t>(el);
|
||||
break;
|
||||
case 'I':
|
||||
in_range = bjdata_ndarray_value_in_range<std::int16_t>(el);
|
||||
break;
|
||||
case 'm':
|
||||
in_range = bjdata_ndarray_value_in_range<std::uint32_t>(el);
|
||||
break;
|
||||
case 'l':
|
||||
in_range = bjdata_ndarray_value_in_range<std::int32_t>(el);
|
||||
break;
|
||||
case 'M':
|
||||
in_range = bjdata_ndarray_value_in_range<std::uint64_t>(el);
|
||||
break;
|
||||
case 'L':
|
||||
in_range = bjdata_ndarray_value_in_range<std::int64_t>(el);
|
||||
break;
|
||||
case 'd':
|
||||
{
|
||||
const auto dval = el.template get<double>();
|
||||
in_range = !std::isfinite(dval) ||
|
||||
(dval >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
|
||||
dval <= static_cast<double>((std::numeric_limits<float>::max)()));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// 'D' (double) already spans the full range of number_float_t
|
||||
break;
|
||||
}
|
||||
if (!in_range)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
oa->write_character('[');
|
||||
oa->write_character('$');
|
||||
oa->write_character(dtype);
|
||||
|
||||
@@ -1335,7 +1335,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief serialization
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/dump/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
string_t dump(const int indent = -1,
|
||||
const char indent_char = ' ',
|
||||
const bool ensure_ascii = false,
|
||||
@@ -1358,7 +1357,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return the type of the JSON value (explicit)
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/type/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr value_t type() const noexcept
|
||||
{
|
||||
return m_data.m_type;
|
||||
@@ -1366,7 +1364,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether type is primitive
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_primitive/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_primitive() const noexcept
|
||||
{
|
||||
return is_null() || is_string() || is_boolean() || is_number() || is_binary();
|
||||
@@ -1374,7 +1371,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether type is structured
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_structured/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_structured() const noexcept
|
||||
{
|
||||
return is_array() || is_object();
|
||||
@@ -1382,7 +1378,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is null
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_null/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_null() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::null;
|
||||
@@ -1390,7 +1385,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is a boolean
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_boolean/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_boolean() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::boolean;
|
||||
@@ -1398,7 +1392,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is a number
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_number/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_number() const noexcept
|
||||
{
|
||||
return is_number_integer() || is_number_float();
|
||||
@@ -1406,7 +1399,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is an integer number
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_number_integer/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_number_integer() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;
|
||||
@@ -1414,7 +1406,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is an unsigned integer number
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_number_unsigned/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_number_unsigned() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::number_unsigned;
|
||||
@@ -1422,7 +1413,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is a floating-point number
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_number_float/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_number_float() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::number_float;
|
||||
@@ -1430,7 +1420,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is an object
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_object/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_object() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::object;
|
||||
@@ -1438,7 +1427,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is an array
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_array/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_array() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::array;
|
||||
@@ -1446,7 +1434,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is a string
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_string/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_string() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::string;
|
||||
@@ -1454,7 +1441,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is a binary array
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_binary/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_binary() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::binary;
|
||||
@@ -1462,7 +1448,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is discarded
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_discarded/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_discarded() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::discarded;
|
||||
@@ -2794,7 +2779,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief returns the number of occurrences of a key in a JSON object
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/count/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
size_type count(const typename object_t::key_type& key) const
|
||||
{
|
||||
// return 0 for all nonobject types
|
||||
@@ -2805,7 +2789,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/count/
|
||||
template<class KeyType, detail::enable_if_t<
|
||||
detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
size_type count(KeyType && key) const
|
||||
{
|
||||
// return 0 for all nonobject types
|
||||
@@ -2814,7 +2797,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief check the existence of an element in a JSON object
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/contains/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
bool contains(const typename object_t::key_type& key) const
|
||||
{
|
||||
return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();
|
||||
@@ -2824,7 +2806,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/contains/
|
||||
template<class KeyType, detail::enable_if_t<
|
||||
detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
bool contains(KeyType && key) const
|
||||
{
|
||||
return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();
|
||||
@@ -2832,14 +2813,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief check the existence of an element in a JSON object given a JSON pointer
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/contains/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
bool contains(const json_pointer& ptr) const
|
||||
{
|
||||
return ptr.contains(this);
|
||||
}
|
||||
|
||||
template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
||||
bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
|
||||
{
|
||||
@@ -2995,7 +2974,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief checks whether the container is empty.
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/empty/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
bool empty() const noexcept
|
||||
{
|
||||
switch (m_data.m_type)
|
||||
@@ -3035,7 +3013,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief returns the number of elements
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/size/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
size_type size() const noexcept
|
||||
{
|
||||
switch (m_data.m_type)
|
||||
@@ -3075,7 +3052,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief returns the maximum possible number of elements
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/max_size/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
size_type max_size() const noexcept
|
||||
{
|
||||
switch (m_data.m_type)
|
||||
@@ -4153,7 +4129,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @brief check if the input is valid JSON
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/accept/
|
||||
template<typename InputType>
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
static bool accept(InputType&& i,
|
||||
const bool ignore_comments = false,
|
||||
const bool ignore_trailing_commas = false)
|
||||
@@ -4165,7 +4140,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/accept/
|
||||
template<typename IteratorType, typename SentinelType = IteratorType,
|
||||
detail::enable_if_t<detail::can_compare_ne<IteratorType, SentinelType>::value, int> = 0>
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
static bool accept(IteratorType first, SentinelType last,
|
||||
const bool ignore_comments = false,
|
||||
const bool ignore_trailing_commas = false)
|
||||
@@ -4265,7 +4239,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return the type as string
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/type_name/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
JSON_HEDLEY_RETURNS_NON_NULL
|
||||
const char* type_name() const noexcept
|
||||
{
|
||||
|
||||
@@ -18655,6 +18655,20 @@ class binary_writer
|
||||
return 'D'; // float 64
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief checks whether a JSON number fits into @a TargetType
|
||||
@param[in] el a JSON number of either the signed or unsigned integer kind
|
||||
@return whether @a el's value can be represented by @a TargetType without
|
||||
wrapping, regardless of which of the two kinds it is stored as
|
||||
*/
|
||||
template<typename TargetType>
|
||||
static bool bjdata_ndarray_value_in_range(const BasicJsonType& el)
|
||||
{
|
||||
return el.is_number_unsigned()
|
||||
? value_in_range_of<TargetType>(el.template get<std::uint64_t>())
|
||||
: value_in_range_of<TargetType>(el.template get<std::int64_t>());
|
||||
}
|
||||
|
||||
/*!
|
||||
@return false if the object is successfully converted to a bjdata ndarray, true if the type or size is invalid
|
||||
*/
|
||||
@@ -18675,6 +18689,16 @@ class binary_writer
|
||||
}
|
||||
CharType dtype = it->second;
|
||||
|
||||
// the 'B' (byte) marker is only defined by BJData Draft 3; emitting it
|
||||
// under the default Draft 2 mode would produce a stream that Draft 2
|
||||
// readers reject, so such an object falls back to a plain object
|
||||
// encoding instead (see the "Binary values" section of the BJData
|
||||
// documentation)
|
||||
if (dtype == 'B' && bjdata_version != bjdata_version_t::draft3)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
key = "_ArraySize_";
|
||||
// the dimensions are written verbatim as the header length below, so a
|
||||
// value that is not an array cannot produce a valid one: null emits 'Z'
|
||||
@@ -18739,6 +18763,60 @@ class binary_writer
|
||||
}
|
||||
}
|
||||
|
||||
// every element is cast to the (possibly narrower) C++ type matching
|
||||
// dtype below; a value that does not fit that type would silently
|
||||
// wrap (integers) or overflow to infinity (the "single" precision
|
||||
// float) instead of being reported, so such an object falls back to
|
||||
// a plain object encoding as well
|
||||
for (const auto& el : value.at(key))
|
||||
{
|
||||
bool in_range = true;
|
||||
switch (dtype)
|
||||
{
|
||||
case 'U':
|
||||
case 'C':
|
||||
case 'B':
|
||||
in_range = bjdata_ndarray_value_in_range<std::uint8_t>(el);
|
||||
break;
|
||||
case 'i':
|
||||
in_range = bjdata_ndarray_value_in_range<std::int8_t>(el);
|
||||
break;
|
||||
case 'u':
|
||||
in_range = bjdata_ndarray_value_in_range<std::uint16_t>(el);
|
||||
break;
|
||||
case 'I':
|
||||
in_range = bjdata_ndarray_value_in_range<std::int16_t>(el);
|
||||
break;
|
||||
case 'm':
|
||||
in_range = bjdata_ndarray_value_in_range<std::uint32_t>(el);
|
||||
break;
|
||||
case 'l':
|
||||
in_range = bjdata_ndarray_value_in_range<std::int32_t>(el);
|
||||
break;
|
||||
case 'M':
|
||||
in_range = bjdata_ndarray_value_in_range<std::uint64_t>(el);
|
||||
break;
|
||||
case 'L':
|
||||
in_range = bjdata_ndarray_value_in_range<std::int64_t>(el);
|
||||
break;
|
||||
case 'd':
|
||||
{
|
||||
const auto dval = el.template get<double>();
|
||||
in_range = !std::isfinite(dval) ||
|
||||
(dval >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
|
||||
dval <= static_cast<double>((std::numeric_limits<float>::max)()));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// 'D' (double) already spans the full range of number_float_t
|
||||
break;
|
||||
}
|
||||
if (!in_range)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
oa->write_character('[');
|
||||
oa->write_character('$');
|
||||
oa->write_character(dtype);
|
||||
@@ -22763,7 +22841,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief serialization
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/dump/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
string_t dump(const int indent = -1,
|
||||
const char indent_char = ' ',
|
||||
const bool ensure_ascii = false,
|
||||
@@ -22786,7 +22863,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return the type of the JSON value (explicit)
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/type/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr value_t type() const noexcept
|
||||
{
|
||||
return m_data.m_type;
|
||||
@@ -22794,7 +22870,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether type is primitive
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_primitive/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_primitive() const noexcept
|
||||
{
|
||||
return is_null() || is_string() || is_boolean() || is_number() || is_binary();
|
||||
@@ -22802,7 +22877,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether type is structured
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_structured/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_structured() const noexcept
|
||||
{
|
||||
return is_array() || is_object();
|
||||
@@ -22810,7 +22884,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is null
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_null/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_null() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::null;
|
||||
@@ -22818,7 +22891,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is a boolean
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_boolean/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_boolean() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::boolean;
|
||||
@@ -22826,7 +22898,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is a number
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_number/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_number() const noexcept
|
||||
{
|
||||
return is_number_integer() || is_number_float();
|
||||
@@ -22834,7 +22905,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is an integer number
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_number_integer/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_number_integer() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;
|
||||
@@ -22842,7 +22912,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is an unsigned integer number
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_number_unsigned/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_number_unsigned() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::number_unsigned;
|
||||
@@ -22850,7 +22919,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is a floating-point number
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_number_float/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_number_float() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::number_float;
|
||||
@@ -22858,7 +22926,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is an object
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_object/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_object() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::object;
|
||||
@@ -22866,7 +22933,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is an array
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_array/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_array() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::array;
|
||||
@@ -22874,7 +22940,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is a string
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_string/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_string() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::string;
|
||||
@@ -22882,7 +22947,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is a binary array
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_binary/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_binary() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::binary;
|
||||
@@ -22890,7 +22954,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return whether value is discarded
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/is_discarded/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
constexpr bool is_discarded() const noexcept
|
||||
{
|
||||
return m_data.m_type == value_t::discarded;
|
||||
@@ -24222,7 +24285,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief returns the number of occurrences of a key in a JSON object
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/count/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
size_type count(const typename object_t::key_type& key) const
|
||||
{
|
||||
// return 0 for all nonobject types
|
||||
@@ -24233,7 +24295,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/count/
|
||||
template<class KeyType, detail::enable_if_t<
|
||||
detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
size_type count(KeyType && key) const
|
||||
{
|
||||
// return 0 for all nonobject types
|
||||
@@ -24242,7 +24303,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief check the existence of an element in a JSON object
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/contains/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
bool contains(const typename object_t::key_type& key) const
|
||||
{
|
||||
return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();
|
||||
@@ -24252,7 +24312,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/contains/
|
||||
template<class KeyType, detail::enable_if_t<
|
||||
detail::is_usable_as_basic_json_key_type<basic_json_t, KeyType>::value, int> = 0>
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
bool contains(KeyType && key) const
|
||||
{
|
||||
return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();
|
||||
@@ -24260,14 +24319,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief check the existence of an element in a JSON object given a JSON pointer
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/contains/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
bool contains(const json_pointer& ptr) const
|
||||
{
|
||||
return ptr.contains(this);
|
||||
}
|
||||
|
||||
template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
|
||||
bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
|
||||
{
|
||||
@@ -24423,7 +24480,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief checks whether the container is empty.
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/empty/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
bool empty() const noexcept
|
||||
{
|
||||
switch (m_data.m_type)
|
||||
@@ -24463,7 +24519,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief returns the number of elements
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/size/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
size_type size() const noexcept
|
||||
{
|
||||
switch (m_data.m_type)
|
||||
@@ -24503,7 +24558,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief returns the maximum possible number of elements
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/max_size/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
size_type max_size() const noexcept
|
||||
{
|
||||
switch (m_data.m_type)
|
||||
@@ -25581,7 +25635,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @brief check if the input is valid JSON
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/accept/
|
||||
template<typename InputType>
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
static bool accept(InputType&& i,
|
||||
const bool ignore_comments = false,
|
||||
const bool ignore_trailing_commas = false)
|
||||
@@ -25593,7 +25646,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/accept/
|
||||
template<typename IteratorType, typename SentinelType = IteratorType,
|
||||
detail::enable_if_t<detail::can_compare_ne<IteratorType, SentinelType>::value, int> = 0>
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
static bool accept(IteratorType first, SentinelType last,
|
||||
const bool ignore_comments = false,
|
||||
const bool ignore_trailing_commas = false)
|
||||
@@ -25693,7 +25745,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief return the type as string
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/type_name/
|
||||
JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
JSON_HEDLEY_RETURNS_NON_NULL
|
||||
const char* type_name() const noexcept
|
||||
{
|
||||
|
||||
@@ -15,15 +15,6 @@
|
||||
namespace utils
|
||||
{
|
||||
|
||||
// Some tests intentionally discard the [[nodiscard]]/JSON_HEDLEY_WARN_UNUSED_RESULT
|
||||
// return value of a call they only make to exercise its side effects (e.g. checking
|
||||
// that it does not throw). A plain (void) cast on the call expression does not
|
||||
// suppress GCC's warning for functions using the GNU __attribute__((warn_unused_result))
|
||||
// form (as opposed to the C++17 [[nodiscard]] attribute) -- passing the value into an
|
||||
// ordinary function call does.
|
||||
template<typename T>
|
||||
inline void ignore_return_value(T&& /*unused*/) noexcept {}
|
||||
|
||||
inline std::vector<std::uint8_t> read_binary_file(const std::string& filename)
|
||||
{
|
||||
std::ifstream file(filename, std::ios::binary);
|
||||
|
||||
@@ -2586,7 +2586,12 @@ TEST_CASE("BJData")
|
||||
CHECK(json::to_bjdata(json::from_bjdata(v_d), true, true) == v_d);
|
||||
CHECK(json::to_bjdata(json::from_bjdata(v_D), true, true) == v_D);
|
||||
CHECK(json::to_bjdata(json::from_bjdata(v_C), true, true) == v_C);
|
||||
CHECK(json::to_bjdata(json::from_bjdata(v_B), true, true) == v_B);
|
||||
// v_B uses the Draft-3-only 'B' marker, so it round-trips only when
|
||||
// Draft 3 is explicitly selected (see GitHub issue #5404); the
|
||||
// default Draft 2 falls back to a plain object instead, covered by
|
||||
// the "ndarray with _ArrayType_ "byte" is gated by the BJData draft
|
||||
// version" section below
|
||||
CHECK(json::to_bjdata(json::from_bjdata(v_B), true, true, json::bjdata_version_t::draft3) == v_B);
|
||||
}
|
||||
|
||||
SECTION("ndarray with data not matching _ArrayType_ is written as an object")
|
||||
@@ -2629,8 +2634,10 @@ TEST_CASE("BJData")
|
||||
// the C++ API stores an int literal as number_integer, so _ArrayType_
|
||||
// names the wire type rather than the storage. Both storages have to
|
||||
// produce the same typed array for every type.
|
||||
// "byte" is checked separately below since it additionally requires
|
||||
// BJData Draft 3 to be selected explicitly (see GitHub issue #5404).
|
||||
for (const char* type :
|
||||
{"uint8", "int8", "uint16", "int16", "uint32", "int32", "uint64", "int64", "char", "byte"
|
||||
{"uint8", "int8", "uint16", "int16", "uint32", "int32", "uint64", "int64", "char"
|
||||
})
|
||||
{
|
||||
CAPTURE(type);
|
||||
@@ -2641,6 +2648,14 @@ TEST_CASE("BJData")
|
||||
CHECK(from_text == json::to_bjdata(json({{"_ArrayType_", type}, {"_ArraySize_", {2, 3}}, {"_ArrayData_", {1, 2, 3, 4, 5, 6}}})));
|
||||
}
|
||||
|
||||
{
|
||||
const std::string text = R"({"_ArrayType_":"byte","_ArraySize_":[2,3],"_ArrayData_":[1,2,3,4,5,6]})";
|
||||
const auto from_text = json::to_bjdata(json::parse(text), true, true, json::bjdata_version_t::draft3);
|
||||
CHECK(from_text.at(0) == '[');
|
||||
CHECK(from_text == json::to_bjdata(json({{"_ArrayType_", "byte"}, {"_ArraySize_", {2, 3}}, {"_ArrayData_", {1, 2, 3, 4, 5, 6}}}),
|
||||
true, true, json::bjdata_version_t::draft3));
|
||||
}
|
||||
|
||||
// negative values under a signed type behave the same way
|
||||
const auto from_neg = json::to_bjdata(json::parse(R"({"_ArrayType_":"int32","_ArraySize_":[2],"_ArrayData_":[-5,7]})"));
|
||||
CHECK(from_neg.at(0) == '[');
|
||||
@@ -2776,6 +2791,83 @@ TEST_CASE("BJData")
|
||||
CHECK(out_num.at(0) == '{');
|
||||
CHECK(json::from_bjdata(out_num) == j_num);
|
||||
}
|
||||
|
||||
SECTION("ndarray with out-of-range _ArrayData_ elements stays as object")
|
||||
{
|
||||
// each element is cast to the (possibly narrower) C++ type
|
||||
// named by _ArrayType_ before being written; a value that
|
||||
// does not fit that type would silently wrap instead of
|
||||
// being reported, so such an object falls back to a plain
|
||||
// object encoding that still round-trips (see GitHub issue #5403)
|
||||
|
||||
// an unsigned element that does not fit uint8
|
||||
json const j_uint8 = json({{"_ArrayType_", "uint8"}, {"_ArraySize_", {2}}, {"_ArrayData_", {1, 256}}});
|
||||
const auto out_uint8 = json::to_bjdata(j_uint8);
|
||||
CHECK(out_uint8.at(0) == '{');
|
||||
CHECK(json::from_bjdata(out_uint8) == j_uint8);
|
||||
|
||||
// a signed element that does not fit int8
|
||||
json const j_int8 = json({{"_ArrayType_", "int8"}, {"_ArraySize_", {2}}, {"_ArrayData_", {1, 200}}});
|
||||
const auto out_int8 = json::to_bjdata(j_int8);
|
||||
CHECK(out_int8.at(0) == '{');
|
||||
CHECK(json::from_bjdata(out_int8) == j_int8);
|
||||
|
||||
// a negative element is likewise out of range for an
|
||||
// unsigned _ArrayType_
|
||||
json const j_uint16_neg = json({{"_ArrayType_", "uint16"}, {"_ArraySize_", {2}}, {"_ArrayData_", {1, -1}}});
|
||||
const auto out_uint16_neg = json::to_bjdata(j_uint16_neg);
|
||||
CHECK(out_uint16_neg.at(0) == '{');
|
||||
CHECK(json::from_bjdata(out_uint16_neg) == j_uint16_neg);
|
||||
|
||||
// a double element that overflows to infinity when narrowed
|
||||
// to the "single" (float) precision named by _ArrayType_
|
||||
json const j_single = json({{"_ArrayType_", "single"}, {"_ArraySize_", {2}}, {"_ArrayData_", {1.5, 1e40}}});
|
||||
const auto out_single = json::to_bjdata(j_single);
|
||||
CHECK(out_single.at(0) == '{');
|
||||
CHECK(json::from_bjdata(out_single) == j_single);
|
||||
|
||||
// in-range boundary values still use the compact ndarray encoding
|
||||
json const j_uint8_ok = json({{"_ArrayType_", "uint8"}, {"_ArraySize_", {2}}, {"_ArrayData_", {0, 255}}});
|
||||
CHECK(json::to_bjdata(j_uint8_ok) == std::vector<uint8_t>({'[', '$', 'U', '#', '[', 'i', 2, ']', 0, 255}));
|
||||
|
||||
json const j_int8_ok = json({{"_ArrayType_", "int8"}, {"_ArraySize_", {2}}, {"_ArrayData_", {-128, 127}}});
|
||||
CHECK(json::to_bjdata(j_int8_ok) == std::vector<uint8_t>({'[', '$', 'i', '#', '[', 'i', 2, ']', 0x80, 0x7F}));
|
||||
|
||||
json const j_single_ok = json({{"_ArrayType_", "single"}, {"_ArraySize_", {1}}, {"_ArrayData_", {1.5}}});
|
||||
const auto out_single_ok = json::to_bjdata(j_single_ok);
|
||||
CHECK(out_single_ok.at(0) == '[');
|
||||
CHECK(json::from_bjdata(out_single_ok) == json({1.5f}));
|
||||
}
|
||||
|
||||
SECTION("ndarray with _ArrayType_ \"byte\" is gated by the BJData draft version")
|
||||
{
|
||||
// the 'B' (byte) marker used by _ArrayType_ "byte" is only defined
|
||||
// by BJData Draft 3; Draft 2 (the default) has no such marker, so
|
||||
// emitting it unconditionally produced a stream that a Draft 2
|
||||
// reader could not parse as intended (see GitHub issue #5404).
|
||||
// Two dimensions are used so that a successfully written ndarray
|
||||
// round-trips back into the annotated object (a single dimension
|
||||
// is, by the BJData ndarray convention, read back as a plain
|
||||
// binary value rather than the annotated object, same as every
|
||||
// other single-dimension ndarray of a non-"byte" type is read
|
||||
// back as a plain array instead of the annotated object).
|
||||
json const j_byte = json({{"_ArrayType_", "byte"}, {"_ArraySize_", {2, 3}}, {"_ArrayData_", {1, 2, 3, 4, 5, 6}}});
|
||||
|
||||
// default (Draft 2): falls back to a plain object and round-trips
|
||||
const auto out_draft2 = json::to_bjdata(j_byte);
|
||||
CHECK(out_draft2.at(0) == '{');
|
||||
CHECK(json::from_bjdata(out_draft2) == j_byte);
|
||||
|
||||
// explicit Draft 2: same as the default
|
||||
const auto out_draft2_explicit = json::to_bjdata(j_byte, true, true, json::bjdata_version_t::draft2);
|
||||
CHECK(out_draft2_explicit.at(0) == '{');
|
||||
CHECK(json::from_bjdata(out_draft2_explicit) == j_byte);
|
||||
|
||||
// Draft 3 explicitly selected: still uses the compact 'B' ndarray encoding
|
||||
const auto out_draft3 = json::to_bjdata(j_byte, true, true, json::bjdata_version_t::draft3);
|
||||
CHECK(out_draft3 == std::vector<uint8_t>({'[', '$', 'B', '#', '[', '$', 'i', '#', 'i', 2, 2, 3, 1, 2, 3, 4, 5, 6}));
|
||||
CHECK(json::from_bjdata(out_draft3) == j_byte);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ using nlohmann::json;
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "test_utils.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
class SaxEventLogger
|
||||
@@ -626,8 +624,7 @@ TEST_CASE("parser class")
|
||||
SECTION("overflow")
|
||||
{
|
||||
// overflows during parsing yield an exception
|
||||
// empty() is nodiscard; the exception is thrown by parser_helper() itself, before empty() would run
|
||||
CHECK_THROWS_WITH_AS(utils::ignore_return_value(parser_helper("1.18973e+4932").empty()), "[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'", json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS(parser_helper("1.18973e+4932").empty(), "[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'", json::out_of_range&);
|
||||
}
|
||||
|
||||
SECTION("invalid numbers")
|
||||
|
||||
@@ -22,8 +22,6 @@ using nlohmann::json;
|
||||
|
||||
#include <valarray>
|
||||
|
||||
#include "test_utils.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
class SaxEventLogger
|
||||
@@ -631,8 +629,7 @@ TEST_CASE("parser class")
|
||||
SECTION("overflow")
|
||||
{
|
||||
// overflows during parsing yield an exception
|
||||
// empty() is nodiscard; the exception is thrown by parser_helper() itself, before empty() would run
|
||||
CHECK_THROWS_WITH_AS(utils::ignore_return_value(parser_helper("1.18973e+4932").empty()), "[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'", json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS(parser_helper("1.18973e+4932").empty(), "[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'", json::out_of_range&);
|
||||
}
|
||||
|
||||
SECTION("invalid numbers")
|
||||
|
||||
@@ -29,7 +29,6 @@ using nlohmann::json;
|
||||
#include <limits>
|
||||
#include <cstdio>
|
||||
#include "make_test_data_available.hpp"
|
||||
#include "test_utils.hpp"
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
#include <variant>
|
||||
@@ -1374,8 +1373,7 @@ TEST_CASE("regression tests 1")
|
||||
std::array<uint8_t, 28> key1 = {{ 103, 92, 117, 48, 48, 48, 55, 92, 114, 215, 126, 214, 95, 92, 34, 174, 40, 71, 38, 174, 40, 71, 38, 223, 134, 247, 127, 0 }};
|
||||
std::string const key1_str(reinterpret_cast<char*>(key1.data()));
|
||||
json const j = key1_str;
|
||||
// dump() is nodiscard; the exception is thrown by dump() itself before it would return
|
||||
CHECK_THROWS_WITH_AS(utils::ignore_return_value(j.dump()), "[json.exception.type_error.316] invalid UTF-8 byte at index 10: 0x7E", json::type_error&);
|
||||
CHECK_THROWS_WITH_AS(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 10: 0x7E", json::type_error&);
|
||||
}
|
||||
|
||||
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||
|
||||
@@ -31,8 +31,6 @@ using ordered_json = nlohmann::ordered_json;
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "test_utils.hpp"
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
#include <any>
|
||||
#include <variant>
|
||||
@@ -641,12 +639,7 @@ TEST_CASE("regression tests 2")
|
||||
s += static_cast<char>(i);
|
||||
}
|
||||
dump_test["1"] = s;
|
||||
// dump() is nodiscard; this only checks that dumping does not throw/crash.
|
||||
// A (void) cast on the call itself does not suppress GCC's warning for the
|
||||
// GNU warn_unused_result attribute (unlike a real C++17 [[nodiscard]]), so
|
||||
// capture the result in a variable and discard that instead.
|
||||
auto dump_result = dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
|
||||
(void)dump_result;
|
||||
dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -738,14 +731,12 @@ TEST_CASE("regression tests 2")
|
||||
{
|
||||
const std::array<unsigned char, 23> data = {{0x81, 0xA4, 0x64, 0x61, 0x74, 0x61, 0xC4, 0x0F, 0x33, 0x30, 0x30, 0x32, 0x33, 0x34, 0x30, 0x31, 0x30, 0x37, 0x30, 0x35, 0x30, 0x31, 0x30}};
|
||||
const json j = json::from_msgpack(data.data(), data.size());
|
||||
// dump() is nodiscard; this only checks that dumping does not throw
|
||||
CHECK_NOTHROW(
|
||||
utils::ignore_return_value(
|
||||
j.dump(4, // Indent
|
||||
' ', // Indent char
|
||||
false, // Ensure ascii
|
||||
json::error_handler_t::strict // Error
|
||||
)));
|
||||
j.dump(4, // Indent
|
||||
' ', // Indent char
|
||||
false, // Ensure ascii
|
||||
json::error_handler_t::strict // Error
|
||||
));
|
||||
}
|
||||
|
||||
SECTION("PR #2181 - regression bug with lvalue")
|
||||
|
||||
@@ -15,8 +15,6 @@ using nlohmann::json;
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "test_utils.hpp"
|
||||
|
||||
TEST_CASE("serialization")
|
||||
{
|
||||
SECTION("operator<<")
|
||||
@@ -86,9 +84,8 @@ TEST_CASE("serialization")
|
||||
{
|
||||
const json j = "ä\xA9ü";
|
||||
|
||||
// dump() is nodiscard; the exception is thrown by dump() itself before it would return
|
||||
CHECK_THROWS_WITH_AS(utils::ignore_return_value(j.dump()), "[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9", json::type_error&);
|
||||
CHECK_THROWS_WITH_AS(utils::ignore_return_value(j.dump(1, ' ', false, json::error_handler_t::strict)), "[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9", json::type_error&);
|
||||
CHECK_THROWS_WITH_AS(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9", json::type_error&);
|
||||
CHECK_THROWS_WITH_AS(j.dump(1, ' ', false, json::error_handler_t::strict), "[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9", json::type_error&);
|
||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::ignore) == "\"äü\"");
|
||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::replace) == "\"ä\xEF\xBF\xBDü\"");
|
||||
CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == "\"\\u00e4\\ufffd\\u00fc\"");
|
||||
@@ -98,9 +95,8 @@ TEST_CASE("serialization")
|
||||
{
|
||||
const json j = "123\xC2";
|
||||
|
||||
// dump() is nodiscard; the exception is thrown by dump() itself before it would return
|
||||
CHECK_THROWS_WITH_AS(utils::ignore_return_value(j.dump()), "[json.exception.type_error.316] incomplete UTF-8 string; last byte: 0xC2", json::type_error&);
|
||||
CHECK_THROWS_AS(utils::ignore_return_value(j.dump(1, ' ', false, json::error_handler_t::strict)), json::type_error&);
|
||||
CHECK_THROWS_WITH_AS(j.dump(), "[json.exception.type_error.316] incomplete UTF-8 string; last byte: 0xC2", json::type_error&);
|
||||
CHECK_THROWS_AS(j.dump(1, ' ', false, json::error_handler_t::strict), json::type_error&);
|
||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::ignore) == "\"123\"");
|
||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::replace) == "\"123\xEF\xBF\xBD\"");
|
||||
CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == "\"123\\ufffd\"");
|
||||
@@ -110,9 +106,8 @@ TEST_CASE("serialization")
|
||||
{
|
||||
const json j = "123\xF1\xB0\x34\x35\x36";
|
||||
|
||||
// dump() is nodiscard; the exception is thrown by dump() itself before it would return
|
||||
CHECK_THROWS_WITH_AS(utils::ignore_return_value(j.dump()), "[json.exception.type_error.316] invalid UTF-8 byte at index 5: 0x34", json::type_error&);
|
||||
CHECK_THROWS_AS(utils::ignore_return_value(j.dump(1, ' ', false, json::error_handler_t::strict)), json::type_error&);
|
||||
CHECK_THROWS_WITH_AS(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 5: 0x34", json::type_error&);
|
||||
CHECK_THROWS_AS(j.dump(1, ' ', false, json::error_handler_t::strict), json::type_error&);
|
||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::ignore) == "\"123456\"");
|
||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::replace) == "\"123\xEF\xBF\xBD\x34\x35\x36\"");
|
||||
CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == "\"123\\ufffd456\"");
|
||||
|
||||
@@ -17,7 +17,6 @@ using nlohmann::json;
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include "make_test_data_available.hpp"
|
||||
#include "test_utils.hpp"
|
||||
|
||||
TEST_CASE("Unicode (1/5)" * doctest::skip())
|
||||
{
|
||||
@@ -241,8 +240,7 @@ void roundtrip(bool success_expected, const std::string& s)
|
||||
if (success_expected)
|
||||
{
|
||||
// serialization succeeds
|
||||
// dump() is nodiscard; this only checks that dumping does not throw
|
||||
CHECK_NOTHROW(utils::ignore_return_value(j.dump()));
|
||||
CHECK_NOTHROW(j.dump());
|
||||
|
||||
// exclude parse test for U+0000
|
||||
if (s[0] != '\0')
|
||||
@@ -261,8 +259,7 @@ void roundtrip(bool success_expected, const std::string& s)
|
||||
else
|
||||
{
|
||||
// serialization fails
|
||||
// dump() is nodiscard; the exception is thrown by dump() itself before it would return
|
||||
CHECK_THROWS_AS(utils::ignore_return_value(j.dump()), json::type_error&);
|
||||
CHECK_THROWS_AS(j.dump(), json::type_error&);
|
||||
|
||||
// parsing JSON text fails
|
||||
CHECK_THROWS_AS(_ = json::parse(ps), json::parse_error&);
|
||||
|
||||
@@ -19,7 +19,6 @@ using nlohmann::json;
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "make_test_data_available.hpp"
|
||||
#include "test_utils.hpp"
|
||||
|
||||
// this test suite uses static variables with non-trivial destructors
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||
@@ -98,8 +97,7 @@ void check_utf8dump(bool success_expected, int byte1, int byte2 = -1, int byte3
|
||||
else
|
||||
{
|
||||
// strict mode must throw if success is not expected
|
||||
// dump() is nodiscard; the exception is thrown by dump() itself before it would return
|
||||
CHECK_THROWS_AS(utils::ignore_return_value(j.dump()), json::type_error&);
|
||||
CHECK_THROWS_AS(j.dump(), json::type_error&);
|
||||
// ignore and replace must create different dumps
|
||||
CHECK(s_ignored != s_replaced);
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ using nlohmann::json;
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "make_test_data_available.hpp"
|
||||
#include "test_utils.hpp"
|
||||
|
||||
// this test suite uses static variables with non-trivial destructors
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||
@@ -98,8 +97,7 @@ void check_utf8dump(bool success_expected, int byte1, int byte2 = -1, int byte3
|
||||
else
|
||||
{
|
||||
// strict mode must throw if success is not expected
|
||||
// dump() is nodiscard; the exception is thrown by dump() itself before it would return
|
||||
CHECK_THROWS_AS(utils::ignore_return_value(j.dump()), json::type_error&);
|
||||
CHECK_THROWS_AS(j.dump(), json::type_error&);
|
||||
// ignore and replace must create different dumps
|
||||
CHECK(s_ignored != s_replaced);
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ using nlohmann::json;
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "make_test_data_available.hpp"
|
||||
#include "test_utils.hpp"
|
||||
|
||||
// this test suite uses static variables with non-trivial destructors
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||
@@ -98,8 +97,7 @@ void check_utf8dump(bool success_expected, int byte1, int byte2 = -1, int byte3
|
||||
else
|
||||
{
|
||||
// strict mode must throw if success is not expected
|
||||
// dump() is nodiscard; the exception is thrown by dump() itself before it would return
|
||||
CHECK_THROWS_AS(utils::ignore_return_value(j.dump()), json::type_error&);
|
||||
CHECK_THROWS_AS(j.dump(), json::type_error&);
|
||||
// ignore and replace must create different dumps
|
||||
CHECK(s_ignored != s_replaced);
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ using nlohmann::json;
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "make_test_data_available.hpp"
|
||||
#include "test_utils.hpp"
|
||||
|
||||
// this test suite uses static variables with non-trivial destructors
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
|
||||
@@ -98,8 +97,7 @@ void check_utf8dump(bool success_expected, int byte1, int byte2 = -1, int byte3
|
||||
else
|
||||
{
|
||||
// strict mode must throw if success is not expected
|
||||
// dump() is nodiscard; the exception is thrown by dump() itself before it would return
|
||||
CHECK_THROWS_AS(utils::ignore_return_value(j.dump()), json::type_error&);
|
||||
CHECK_THROWS_AS(j.dump(), json::type_error&);
|
||||
// ignore and replace must create different dumps
|
||||
CHECK(s_ignored != s_replaced);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user