Merge branch 'develop' into iterate-on-destruction
This commit is contained in:
commit
372c4d2125
12 changed files with 225 additions and 11 deletions
|
@ -165,6 +165,8 @@ If you are using [CocoaPods](https://cocoapods.org), you can use the library by
|
||||||
|
|
||||||
If you are using [NuGet](https://www.nuget.org), you can use the package [nlohmann.json](https://www.nuget.org/packages/nlohmann.json/). Please check [this extensive description](https://github.com/nlohmann/json/issues/1132#issuecomment-452250255) on how to use the package. Please files issues [here](https://github.com/hnkb/nlohmann-json-nuget/issues).
|
If you are using [NuGet](https://www.nuget.org), you can use the package [nlohmann.json](https://www.nuget.org/packages/nlohmann.json/). Please check [this extensive description](https://github.com/nlohmann/json/issues/1132#issuecomment-452250255) on how to use the package. Please files issues [here](https://github.com/hnkb/nlohmann-json-nuget/issues).
|
||||||
|
|
||||||
|
If you are using [conda](https://conda.io/), you can use the package [nlohmann_json](https://github.com/conda-forge/nlohmann_json-feedstock) from [conda-forge](https://conda-forge.org) executing `conda install -c conda-forge nlohmann_json`. Please file issues [here](https://github.com/conda-forge/nlohmann_json-feedstock/issues).
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Beside the examples below, you may want to check the [documentation](https://nlohmann.github.io/json/) where each function contains a separate code example (e.g., check out [`emplace()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a5338e282d1d02bed389d852dd670d98d.html#a5338e282d1d02bed389d852dd670d98d)). All [example files](https://github.com/nlohmann/json/tree/develop/doc/examples) can be compiled and executed on their own (e.g., file [emplace.cpp](https://github.com/nlohmann/json/blob/develop/doc/examples/emplace.cpp)).
|
Beside the examples below, you may want to check the [documentation](https://nlohmann.github.io/json/) where each function contains a separate code example (e.g., check out [`emplace()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a5338e282d1d02bed389d852dd670d98d.html#a5338e282d1d02bed389d852dd670d98d)). All [example files](https://github.com/nlohmann/json/tree/develop/doc/examples) can be compiled and executed on their own (e.g., file [emplace.cpp](https://github.com/nlohmann/json/blob/develop/doc/examples/emplace.cpp)).
|
||||||
|
@ -747,7 +749,7 @@ Likewise, when calling `get<your_type>()` or `get_to(your_type&)`, the `from_jso
|
||||||
Some important things:
|
Some important things:
|
||||||
|
|
||||||
* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).
|
* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).
|
||||||
* Those methods **MUST** be available (e.g., properly headers must be included) everywhere you use these conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.
|
* Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.
|
||||||
* When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)
|
* When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)
|
||||||
* In function `from_json`, use function [`at()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a93403e803947b86f4da2d1fb3345cf2c.html#a93403e803947b86f4da2d1fb3345cf2c) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.
|
* In function `from_json`, use function [`at()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a93403e803947b86f4da2d1fb3345cf2c.html#a93403e803947b86f4da2d1fb3345cf2c) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.
|
||||||
* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.
|
* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.
|
||||||
|
@ -915,7 +917,7 @@ NLOHMANN_JSON_SERIALIZE_ENUM( TaskState, {
|
||||||
{TS_STOPPED, "stopped"},
|
{TS_STOPPED, "stopped"},
|
||||||
{TS_RUNNING, "running"},
|
{TS_RUNNING, "running"},
|
||||||
{TS_COMPLETED, "completed"},
|
{TS_COMPLETED, "completed"},
|
||||||
});
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `NLOHMANN_JSON_SERIALIZE_ENUM()` macro declares a set of `to_json()` / `from_json()` functions for type `TaskState` while avoiding repetition and boilerplate serilization code.
|
The `NLOHMANN_JSON_SERIALIZE_ENUM()` macro declares a set of `to_json()` / `from_json()` functions for type `TaskState` while avoiding repetition and boilerplate serilization code.
|
||||||
|
|
|
@ -97,7 +97,6 @@ class json_pointer
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
/*!
|
/*!
|
||||||
@brief remove and return last reference pointer
|
@brief remove and return last reference pointer
|
||||||
@throw out_of_range.405 if JSON pointer has no parent
|
@throw out_of_range.405 if JSON pointer has no parent
|
||||||
|
@ -114,6 +113,16 @@ class json_pointer
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief remove and return last reference pointer
|
||||||
|
@throw out_of_range.405 if JSON pointer has no parent
|
||||||
|
*/
|
||||||
|
void push_back(const std::string& tok)
|
||||||
|
{
|
||||||
|
reference_tokens.push_back(tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
/// return whether pointer points to the root document
|
/// return whether pointer points to the root document
|
||||||
bool is_root() const noexcept
|
bool is_root() const noexcept
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,6 +37,19 @@
|
||||||
#define JSON_DEPRECATED
|
#define JSON_DEPRECATED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// allow for portable nodiscard warnings
|
||||||
|
#if defined(__has_cpp_attribute)
|
||||||
|
#if __has_cpp_attribute(nodiscard)
|
||||||
|
#define JSON_NODISCARD [[nodiscard]]
|
||||||
|
#elif __has_cpp_attribute(gnu::warn_unused_result)
|
||||||
|
#define JSON_NODISCARD [[gnu::warn_unused_result]]
|
||||||
|
#else
|
||||||
|
#define JSON_NODISCARD
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define JSON_NODISCARD
|
||||||
|
#endif
|
||||||
|
|
||||||
// allow to disable exceptions
|
// allow to disable exceptions
|
||||||
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
|
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
|
||||||
#define JSON_THROW(exception) throw exception
|
#define JSON_THROW(exception) throw exception
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#undef JSON_LIKELY
|
#undef JSON_LIKELY
|
||||||
#undef JSON_UNLIKELY
|
#undef JSON_UNLIKELY
|
||||||
#undef JSON_DEPRECATED
|
#undef JSON_DEPRECATED
|
||||||
|
#undef JSON_NODISCARD
|
||||||
#undef JSON_HAS_CPP_14
|
#undef JSON_HAS_CPP_14
|
||||||
#undef JSON_HAS_CPP_17
|
#undef JSON_HAS_CPP_17
|
||||||
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
|
|
|
@ -454,6 +454,16 @@ class serializer
|
||||||
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
|
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
|
||||||
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
|
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write buffer and reset index; there must be 13 bytes
|
||||||
|
// left, as this is the maximal number of bytes to be
|
||||||
|
// written ("\uxxxx\uxxxx\0") for one code point
|
||||||
|
if (string_buffer.size() - bytes < 13)
|
||||||
|
{
|
||||||
|
o->write_characters(string_buffer.data(), bytes);
|
||||||
|
bytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
bytes_after_last_accept = bytes;
|
bytes_after_last_accept = bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,7 +620,7 @@ class serializer
|
||||||
if (is_negative)
|
if (is_negative)
|
||||||
{
|
{
|
||||||
*buffer_ptr = '-';
|
*buffer_ptr = '-';
|
||||||
abs_value = static_cast<number_unsigned_t>(0 - x);
|
abs_value = static_cast<number_unsigned_t>(-1 - x) + 1;
|
||||||
|
|
||||||
// account one more byte for the minus sign
|
// account one more byte for the minus sign
|
||||||
n_chars = 1 + count_digits(abs_value);
|
n_chars = 1 + count_digits(abs_value);
|
||||||
|
@ -630,7 +640,6 @@ class serializer
|
||||||
|
|
||||||
// Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
|
// Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
|
||||||
// See: https://www.youtube.com/watch?v=o4-CwDo2zpg
|
// See: https://www.youtube.com/watch?v=o4-CwDo2zpg
|
||||||
const auto buffer_end = buffer_ptr;
|
|
||||||
while (abs_value >= 100)
|
while (abs_value >= 100)
|
||||||
{
|
{
|
||||||
const auto digits_index = static_cast<unsigned>((abs_value % 100));
|
const auto digits_index = static_cast<unsigned>((abs_value % 100));
|
||||||
|
|
|
@ -317,6 +317,7 @@ class basic_json
|
||||||
|
|
||||||
@since 2.1.0
|
@since 2.1.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json meta()
|
static basic_json meta()
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
|
@ -1538,6 +1539,7 @@ class basic_json
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json array(initializer_list_t init = {})
|
static basic_json array(initializer_list_t init = {})
|
||||||
{
|
{
|
||||||
return basic_json(init, false, value_t::array);
|
return basic_json(init, false, value_t::array);
|
||||||
|
@ -1581,6 +1583,7 @@ class basic_json
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json object(initializer_list_t init = {})
|
static basic_json object(initializer_list_t init = {})
|
||||||
{
|
{
|
||||||
return basic_json(init, false, value_t::object);
|
return basic_json(init, false, value_t::object);
|
||||||
|
@ -6100,6 +6103,7 @@ class basic_json
|
||||||
|
|
||||||
@since version 2.0.3 (contiguous containers)
|
@since version 2.0.3 (contiguous containers)
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json parse(detail::input_adapter&& i,
|
static basic_json parse(detail::input_adapter&& i,
|
||||||
const parser_callback_t cb = nullptr,
|
const parser_callback_t cb = nullptr,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -6875,6 +6879,7 @@ class basic_json
|
||||||
@a strict parameter since 3.0.0; added @a allow_exceptions parameter
|
@a strict parameter since 3.0.0; added @a allow_exceptions parameter
|
||||||
since 3.2.0
|
since 3.2.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_cbor(detail::input_adapter&& i,
|
static basic_json from_cbor(detail::input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -6890,6 +6895,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
template<typename A1, typename A2,
|
template<typename A1, typename A2,
|
||||||
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_cbor(A1 && a1, A2 && a2,
|
static basic_json from_cbor(A1 && a1, A2 && a2,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -6982,6 +6988,7 @@ class basic_json
|
||||||
@a strict parameter since 3.0.0; added @a allow_exceptions parameter
|
@a strict parameter since 3.0.0; added @a allow_exceptions parameter
|
||||||
since 3.2.0
|
since 3.2.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_msgpack(detail::input_adapter&& i,
|
static basic_json from_msgpack(detail::input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -6997,6 +7004,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
template<typename A1, typename A2,
|
template<typename A1, typename A2,
|
||||||
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_msgpack(A1 && a1, A2 && a2,
|
static basic_json from_msgpack(A1 && a1, A2 && a2,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -7068,6 +7076,7 @@ class basic_json
|
||||||
|
|
||||||
@since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
|
@since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_ubjson(detail::input_adapter&& i,
|
static basic_json from_ubjson(detail::input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -7083,6 +7092,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
template<typename A1, typename A2,
|
template<typename A1, typename A2,
|
||||||
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_ubjson(A1 && a1, A2 && a2,
|
static basic_json from_ubjson(A1 && a1, A2 && a2,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -7153,6 +7163,7 @@ class basic_json
|
||||||
@sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
|
@sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
|
||||||
related UBJSON format
|
related UBJSON format
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_bson(detail::input_adapter&& i,
|
static basic_json from_bson(detail::input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -7168,6 +7179,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
template<typename A1, typename A2,
|
template<typename A1, typename A2,
|
||||||
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_bson(A1 && a1, A2 && a2,
|
static basic_json from_bson(A1 && a1, A2 && a2,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -7759,6 +7771,7 @@ class basic_json
|
||||||
|
|
||||||
@since version 2.0.0
|
@since version 2.0.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json diff(const basic_json& source, const basic_json& target,
|
static basic_json diff(const basic_json& source, const basic_json& target,
|
||||||
const std::string& path = "")
|
const std::string& path = "")
|
||||||
{
|
{
|
||||||
|
|
|
@ -152,6 +152,19 @@ using json = basic_json<>;
|
||||||
#define JSON_DEPRECATED
|
#define JSON_DEPRECATED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// allow for portable nodiscard warnings
|
||||||
|
#if defined(__has_cpp_attribute)
|
||||||
|
#if __has_cpp_attribute(nodiscard)
|
||||||
|
#define JSON_NODISCARD [[nodiscard]]
|
||||||
|
#elif __has_cpp_attribute(gnu::warn_unused_result)
|
||||||
|
#define JSON_NODISCARD [[gnu::warn_unused_result]]
|
||||||
|
#else
|
||||||
|
#define JSON_NODISCARD
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define JSON_NODISCARD
|
||||||
|
#endif
|
||||||
|
|
||||||
// allow to disable exceptions
|
// allow to disable exceptions
|
||||||
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
|
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
|
||||||
#define JSON_THROW(exception) throw exception
|
#define JSON_THROW(exception) throw exception
|
||||||
|
@ -11344,6 +11357,16 @@ class serializer
|
||||||
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
|
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
|
||||||
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
|
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write buffer and reset index; there must be 13 bytes
|
||||||
|
// left, as this is the maximal number of bytes to be
|
||||||
|
// written ("\uxxxx\uxxxx\0") for one code point
|
||||||
|
if (string_buffer.size() - bytes < 13)
|
||||||
|
{
|
||||||
|
o->write_characters(string_buffer.data(), bytes);
|
||||||
|
bytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
bytes_after_last_accept = bytes;
|
bytes_after_last_accept = bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11500,7 +11523,7 @@ class serializer
|
||||||
if (is_negative)
|
if (is_negative)
|
||||||
{
|
{
|
||||||
*buffer_ptr = '-';
|
*buffer_ptr = '-';
|
||||||
abs_value = static_cast<number_unsigned_t>(0 - x);
|
abs_value = static_cast<number_unsigned_t>(-1 - x) + 1;
|
||||||
|
|
||||||
// account one more byte for the minus sign
|
// account one more byte for the minus sign
|
||||||
n_chars = 1 + count_digits(abs_value);
|
n_chars = 1 + count_digits(abs_value);
|
||||||
|
@ -11520,7 +11543,6 @@ class serializer
|
||||||
|
|
||||||
// Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
|
// Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
|
||||||
// See: https://www.youtube.com/watch?v=o4-CwDo2zpg
|
// See: https://www.youtube.com/watch?v=o4-CwDo2zpg
|
||||||
const auto buffer_end = buffer_ptr;
|
|
||||||
while (abs_value >= 100)
|
while (abs_value >= 100)
|
||||||
{
|
{
|
||||||
const auto digits_index = static_cast<unsigned>((abs_value % 100));
|
const auto digits_index = static_cast<unsigned>((abs_value % 100));
|
||||||
|
@ -11885,7 +11907,6 @@ class json_pointer
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
/*!
|
/*!
|
||||||
@brief remove and return last reference pointer
|
@brief remove and return last reference pointer
|
||||||
@throw out_of_range.405 if JSON pointer has no parent
|
@throw out_of_range.405 if JSON pointer has no parent
|
||||||
|
@ -11902,6 +11923,16 @@ class json_pointer
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief remove and return last reference pointer
|
||||||
|
@throw out_of_range.405 if JSON pointer has no parent
|
||||||
|
*/
|
||||||
|
void push_back(const std::string& tok)
|
||||||
|
{
|
||||||
|
reference_tokens.push_back(tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
/// return whether pointer points to the root document
|
/// return whether pointer points to the root document
|
||||||
bool is_root() const noexcept
|
bool is_root() const noexcept
|
||||||
{
|
{
|
||||||
|
@ -12785,6 +12816,7 @@ class basic_json
|
||||||
|
|
||||||
@since 2.1.0
|
@since 2.1.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json meta()
|
static basic_json meta()
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
|
@ -14006,6 +14038,7 @@ class basic_json
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json array(initializer_list_t init = {})
|
static basic_json array(initializer_list_t init = {})
|
||||||
{
|
{
|
||||||
return basic_json(init, false, value_t::array);
|
return basic_json(init, false, value_t::array);
|
||||||
|
@ -14049,6 +14082,7 @@ class basic_json
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json object(initializer_list_t init = {})
|
static basic_json object(initializer_list_t init = {})
|
||||||
{
|
{
|
||||||
return basic_json(init, false, value_t::object);
|
return basic_json(init, false, value_t::object);
|
||||||
|
@ -18568,6 +18602,7 @@ class basic_json
|
||||||
|
|
||||||
@since version 2.0.3 (contiguous containers)
|
@since version 2.0.3 (contiguous containers)
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json parse(detail::input_adapter&& i,
|
static basic_json parse(detail::input_adapter&& i,
|
||||||
const parser_callback_t cb = nullptr,
|
const parser_callback_t cb = nullptr,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -19343,6 +19378,7 @@ class basic_json
|
||||||
@a strict parameter since 3.0.0; added @a allow_exceptions parameter
|
@a strict parameter since 3.0.0; added @a allow_exceptions parameter
|
||||||
since 3.2.0
|
since 3.2.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_cbor(detail::input_adapter&& i,
|
static basic_json from_cbor(detail::input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -19358,6 +19394,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
template<typename A1, typename A2,
|
template<typename A1, typename A2,
|
||||||
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_cbor(A1 && a1, A2 && a2,
|
static basic_json from_cbor(A1 && a1, A2 && a2,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -19450,6 +19487,7 @@ class basic_json
|
||||||
@a strict parameter since 3.0.0; added @a allow_exceptions parameter
|
@a strict parameter since 3.0.0; added @a allow_exceptions parameter
|
||||||
since 3.2.0
|
since 3.2.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_msgpack(detail::input_adapter&& i,
|
static basic_json from_msgpack(detail::input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -19465,6 +19503,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
template<typename A1, typename A2,
|
template<typename A1, typename A2,
|
||||||
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_msgpack(A1 && a1, A2 && a2,
|
static basic_json from_msgpack(A1 && a1, A2 && a2,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -19536,6 +19575,7 @@ class basic_json
|
||||||
|
|
||||||
@since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
|
@since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_ubjson(detail::input_adapter&& i,
|
static basic_json from_ubjson(detail::input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -19551,6 +19591,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
template<typename A1, typename A2,
|
template<typename A1, typename A2,
|
||||||
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_ubjson(A1 && a1, A2 && a2,
|
static basic_json from_ubjson(A1 && a1, A2 && a2,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -19621,6 +19662,7 @@ class basic_json
|
||||||
@sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
|
@sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
|
||||||
related UBJSON format
|
related UBJSON format
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_bson(detail::input_adapter&& i,
|
static basic_json from_bson(detail::input_adapter&& i,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -19636,6 +19678,7 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
template<typename A1, typename A2,
|
template<typename A1, typename A2,
|
||||||
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json from_bson(A1 && a1, A2 && a2,
|
static basic_json from_bson(A1 && a1, A2 && a2,
|
||||||
const bool strict = true,
|
const bool strict = true,
|
||||||
const bool allow_exceptions = true)
|
const bool allow_exceptions = true)
|
||||||
|
@ -20227,6 +20270,7 @@ class basic_json
|
||||||
|
|
||||||
@since version 2.0.0
|
@since version 2.0.0
|
||||||
*/
|
*/
|
||||||
|
JSON_NODISCARD
|
||||||
static basic_json diff(const basic_json& source, const basic_json& target,
|
static basic_json diff(const basic_json& source, const basic_json& target,
|
||||||
const std::string& path = "")
|
const std::string& path = "")
|
||||||
{
|
{
|
||||||
|
@ -20546,6 +20590,7 @@ inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std
|
||||||
#undef JSON_LIKELY
|
#undef JSON_LIKELY
|
||||||
#undef JSON_UNLIKELY
|
#undef JSON_UNLIKELY
|
||||||
#undef JSON_DEPRECATED
|
#undef JSON_DEPRECATED
|
||||||
|
#undef JSON_NODISCARD
|
||||||
#undef JSON_HAS_CPP_14
|
#undef JSON_HAS_CPP_14
|
||||||
#undef JSON_HAS_CPP_17
|
#undef JSON_HAS_CPP_17
|
||||||
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||||
|
|
|
@ -1962,7 +1962,7 @@ TEST_CASE("all CBOR first bytes", "[!throws]")
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
json::from_cbor(std::vector<uint8_t>(1, byte));
|
auto res = json::from_cbor(std::vector<uint8_t>(1, byte));
|
||||||
}
|
}
|
||||||
catch (const json::parse_error& e)
|
catch (const json::parse_error& e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -459,4 +459,58 @@ TEST_CASE("JSON pointers")
|
||||||
CHECK(j.is_object());
|
CHECK(j.is_object());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("push and pop")
|
||||||
|
{
|
||||||
|
const json j =
|
||||||
|
{
|
||||||
|
{"", "Hello"},
|
||||||
|
{"pi", 3.141},
|
||||||
|
{"happy", true},
|
||||||
|
{"name", "Niels"},
|
||||||
|
{"nothing", nullptr},
|
||||||
|
{
|
||||||
|
"answer", {
|
||||||
|
{"everything", 42}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{"list", {1, 0, 2}},
|
||||||
|
{
|
||||||
|
"object", {
|
||||||
|
{"currency", "USD"},
|
||||||
|
{"value", 42.99},
|
||||||
|
{"", "empty string"},
|
||||||
|
{"/", "slash"},
|
||||||
|
{"~", "tilde"},
|
||||||
|
{"~1", "tilde1"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// empty json_pointer returns the root JSON-object
|
||||||
|
auto ptr = ""_json_pointer;
|
||||||
|
CHECK(j[ptr] == j);
|
||||||
|
|
||||||
|
// simple field access
|
||||||
|
ptr.push_back("pi");
|
||||||
|
CHECK(j[ptr] == j["pi"]);
|
||||||
|
|
||||||
|
ptr.pop_back();
|
||||||
|
CHECK(j[ptr] == j);
|
||||||
|
|
||||||
|
// object and children access
|
||||||
|
ptr.push_back("answer");
|
||||||
|
ptr.push_back("everything");
|
||||||
|
CHECK(j[ptr] == j["answer"]["everything"]);
|
||||||
|
|
||||||
|
ptr.pop_back();
|
||||||
|
ptr.pop_back();
|
||||||
|
CHECK(j[ptr] == j);
|
||||||
|
|
||||||
|
// push key which has to be encoded
|
||||||
|
ptr.push_back("object");
|
||||||
|
ptr.push_back("/");
|
||||||
|
CHECK(j[ptr] == j["object"]["/"]);
|
||||||
|
CHECK(ptr.to_string() == "/object/~1");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,7 +305,7 @@ TEST_CASE("README", "[hide]")
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// calculate a JSON patch from two JSON values
|
// calculate a JSON patch from two JSON values
|
||||||
json::diff(j_result, j_original);
|
auto res = json::diff(j_result, j_original);
|
||||||
// [
|
// [
|
||||||
// { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] },
|
// { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] },
|
||||||
// { "op":"remove","path":"/hello" },
|
// { "op":"remove","path":"/hello" },
|
||||||
|
|
|
@ -1718,6 +1718,74 @@ TEST_CASE("regression tests")
|
||||||
|
|
||||||
CHECK_NOTHROW(nlohmann::json::parse(s));
|
CHECK_NOTHROW(nlohmann::json::parse(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("issue #1445 - buffer overflow in dumping invalid utf-8 strings")
|
||||||
|
{
|
||||||
|
SECTION("a bunch of -1, ensure_ascii=true")
|
||||||
|
{
|
||||||
|
json dump_test;
|
||||||
|
std::vector<char> data(300, -1);
|
||||||
|
std::vector<std::string> vec_string(300, "\\ufffd");
|
||||||
|
std::string s{data.data(), data.size()};
|
||||||
|
dump_test["1"] = s;
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "{\"1\":\"";
|
||||||
|
std::copy( vec_string.begin(), vec_string.end(), std::ostream_iterator<std::string>(os));
|
||||||
|
os << "\"}";
|
||||||
|
s = dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
|
||||||
|
CHECK(s == os.str());
|
||||||
|
}
|
||||||
|
SECTION("a bunch of -2, ensure_ascii=false")
|
||||||
|
{
|
||||||
|
json dump_test;
|
||||||
|
std::vector<char> data(500, -2);
|
||||||
|
std::vector<std::string> vec_string(500, "\xEF\xBF\xBD");
|
||||||
|
std::string s{data.data(), data.size()};
|
||||||
|
dump_test["1"] = s;
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "{\"1\":\"";
|
||||||
|
std::copy( vec_string.begin(), vec_string.end(), std::ostream_iterator<std::string>(os));
|
||||||
|
os << "\"}";
|
||||||
|
s = dump_test.dump(-1, ' ', false, nlohmann::json::error_handler_t::replace);
|
||||||
|
CHECK(s == os.str());
|
||||||
|
}
|
||||||
|
SECTION("test case in issue #1445")
|
||||||
|
{
|
||||||
|
nlohmann::json dump_test;
|
||||||
|
const int data[] =
|
||||||
|
{
|
||||||
|
109, 108, 103, 125, -122, -53, 115,
|
||||||
|
18, 3, 0, 102, 19, 1, 15,
|
||||||
|
-110, 13, -3, -1, -81, 32, 2,
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, -80, 2,
|
||||||
|
0, 0, 96, -118, 46, -116, 46,
|
||||||
|
109, -84, -87, 108, 14, 109, -24,
|
||||||
|
-83, 13, -18, -51, -83, -52, -115,
|
||||||
|
14, 6, 32, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
64, 3, 0, 0, 0, 35, -74,
|
||||||
|
-73, 55, 57, -128, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 33, 0, 0, 0, -96,
|
||||||
|
-54, -28, -26
|
||||||
|
};
|
||||||
|
std::string s;
|
||||||
|
for (int i = 0; i < sizeof(data) / sizeof(int); i++)
|
||||||
|
{
|
||||||
|
s += static_cast<char>(data[i]);
|
||||||
|
}
|
||||||
|
dump_test["1"] = s;
|
||||||
|
dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("issue #1447 - Integer Overflow (OSS-Fuzz 12506)")
|
||||||
|
{
|
||||||
|
json j = json::parse("[-9223372036854775808]");
|
||||||
|
CHECK(j.dump() == "[-9223372036854775808]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("regression tests, exceptions dependent", "[!throws]")
|
TEST_CASE("regression tests, exceptions dependent", "[!throws]")
|
||||||
|
|
|
@ -2128,7 +2128,7 @@ TEST_CASE("all UBJSON first bytes", "[!throws]")
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
json::from_ubjson(std::vector<uint8_t>(1, byte));
|
auto res = json::from_ubjson(std::vector<uint8_t>(1, byte));
|
||||||
}
|
}
|
||||||
catch (const json::parse_error& e)
|
catch (const json::parse_error& e)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue