mirror of
https://github.com/nlohmann/json
synced 2025-01-13 02:40:06 +00:00
commit
176d8e261a
@ -34,6 +34,7 @@ option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ${M
|
||||
option(JSON_Install "Install CMake targets during install step." ${MAIN_PROJECT})
|
||||
option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OFF)
|
||||
option(JSON_ImplicitConversions "Enable implicit conversions." ON)
|
||||
option(JSON_Diagnostics "Enable better diagnostic messages." OFF)
|
||||
|
||||
##
|
||||
## CONFIGURATION
|
||||
@ -63,6 +64,10 @@ if (NOT JSON_ImplicitConversions)
|
||||
message(STATUS "Implicit conversions are disabled")
|
||||
endif()
|
||||
|
||||
if (JSON_Diagnostics)
|
||||
message(STATUS "Diagnostics enabled")
|
||||
endif()
|
||||
|
||||
##
|
||||
## TARGET
|
||||
## create target and add include path
|
||||
@ -79,6 +84,7 @@ target_compile_definitions(
|
||||
${NLOHMANN_JSON_TARGET_NAME}
|
||||
INTERFACE
|
||||
JSON_USE_IMPLICIT_CONVERSIONS=$<BOOL:${JSON_ImplicitConversions}>
|
||||
JSON_DIAGNOSTICS=$<BOOL:${JSON_Diagnostics}>
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
|
22
doc/examples/diagnostics_extended.cpp
Normal file
22
doc/examples/diagnostics_extended.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include <iostream>
|
||||
|
||||
# define JSON_DIAGNOSTICS 1
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
json j;
|
||||
j["address"]["street"] = "Fake Street";
|
||||
j["address"]["housenumber"] = "12";
|
||||
|
||||
try
|
||||
{
|
||||
int housenumber = j["address"]["housenumber"];
|
||||
}
|
||||
catch (json::exception& e)
|
||||
{
|
||||
std::cout << e.what() << '\n';
|
||||
}
|
||||
}
|
1
doc/examples/diagnostics_extended.link
Normal file
1
doc/examples/diagnostics_extended.link
Normal file
@ -0,0 +1 @@
|
||||
<a target="_blank" href="https://wandbox.org/permlink/pbz3ULoJ4maRnV8N"><b>online</b></a>
|
1
doc/examples/diagnostics_extended.output
Normal file
1
doc/examples/diagnostics_extended.output
Normal file
@ -0,0 +1 @@
|
||||
[json.exception.type_error.302] (/address/housenumber) type must be number, but is string
|
20
doc/examples/diagnostics_standard.cpp
Normal file
20
doc/examples/diagnostics_standard.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
json j;
|
||||
j["address"]["street"] = "Fake Street";
|
||||
j["address"]["housenumber"] = "12";
|
||||
|
||||
try
|
||||
{
|
||||
int housenumber = j["address"]["housenumber"];
|
||||
}
|
||||
catch (json::exception& e)
|
||||
{
|
||||
std::cout << e.what() << '\n';
|
||||
}
|
||||
}
|
1
doc/examples/diagnostics_standard.link
Normal file
1
doc/examples/diagnostics_standard.link
Normal file
@ -0,0 +1 @@
|
||||
<a target="_blank" href="https://wandbox.org/permlink/fWfQhHzG03P6PAcC"><b>online</b></a>
|
1
doc/examples/diagnostics_standard.output
Normal file
1
doc/examples/diagnostics_standard.output
Normal file
@ -0,0 +1 @@
|
||||
[json.exception.type_error.302] type must be number, but is string
|
@ -12,6 +12,14 @@ This macro overrides `#!cpp catch` calls inside the library. The argument is the
|
||||
|
||||
See [Switch off exceptions](../home/exceptions.md#switch-off-exceptions) for an example.
|
||||
|
||||
## `JSON_DIAGNOSTICS`
|
||||
|
||||
This macro enables extended diagnostics for exception messages. Possible values are `1` to enable or `0` to disable (default).
|
||||
|
||||
When enabled, exception messages contain a [JSON Pointer](json_pointer.md) to the JSON value that triggered the exception, see [Extended diagnostic messages](../home/exceptions.md#extended-diagnostic-messages) for an example. Note that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead.
|
||||
|
||||
The diagnostics messages can also be controlled with the CMake option `JSON_Diagnostics` (`OFF` by default) which sets `JSON_DIAGNOSTICS` accordingly.
|
||||
|
||||
## `JSON_NOEXCEPTION`
|
||||
|
||||
Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`.
|
||||
@ -56,6 +64,8 @@ When defined to `0`, implicit conversions are switched off. By default, implicit
|
||||
auto s = j.get<std::string>();
|
||||
```
|
||||
|
||||
Implicit conversions can also be controlled with the CMake option `JSON_ImplicitConversions` (`ON` by default) which sets `JSON_USE_IMPLICIT_CONVERSIONS` accordingly.
|
||||
|
||||
## `NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)`
|
||||
|
||||
This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object.
|
||||
|
@ -50,6 +50,43 @@ Note that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or
|
||||
#include <nlohmann/json.hpp>
|
||||
```
|
||||
|
||||
### Extended diagnostic messages
|
||||
|
||||
Exceptions in the library are thrown in the local context of the JSON value they are detected. This makes detailed diagnostics messages, and hence debugging, difficult.
|
||||
|
||||
??? example
|
||||
|
||||
```cpp
|
||||
--8<-- "examples/diagnostics_standard.cpp"
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
--8<-- "examples/diagnostics_standard.output"
|
||||
```
|
||||
|
||||
This exception can be hard to debug if storing the value `#!c "12"` and accessing it is further apart.
|
||||
|
||||
To create better diagnostics messages, each JSON value needs a pointer to its parent value such that a global context (i.e., a path from the root value to the value that lead to the exception) can be created. That global context is provided as [JSON Pointer](../features/json_pointer.md).
|
||||
|
||||
As this global context comes at the price of storing one additional pointer per JSON value and runtime overhead to maintain the parent relation, extended diagnostics are disabled by default. They can, however, be enabled by defining the preprocessor symbol [`JSON_DIAGNOSTICS`](../features/macros.md#json_diagnostics) to `1` before including `json.hpp`.
|
||||
|
||||
??? example
|
||||
|
||||
```cpp
|
||||
--8<-- "examples/diagnostics_extended.cpp"
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
--8<-- "examples/diagnostics_extended.output"
|
||||
```
|
||||
|
||||
Now the exception message contains a JSON Pointer `/address/housenumber` that indicates which value has the wrong type.
|
||||
|
||||
|
||||
## Parse errors
|
||||
|
||||
This exception is thrown by the library when a parse error occurs. Parse errors
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
The class is licensed under the [MIT License](https://opensource.org/licenses/MIT):
|
||||
|
||||
Copyright © 2013-2020 [Niels Lohmann](https://nlohmann.me)
|
||||
Copyright © 2013-2021 [Niels Lohmann](https://nlohmann.me)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
@ -27,7 +27,7 @@ void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
n = nullptr;
|
||||
}
|
||||
@ -58,7 +58,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
|
||||
}
|
||||
|
||||
default:
|
||||
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
|
||||
}
|
||||
@ -77,7 +77,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
||||
}
|
||||
@ -93,7 +93,7 @@ void from_json(const BasicJsonType& j, ConstructibleStringType& s)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
|
||||
s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
||||
@ -133,7 +133,7 @@ void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
l.clear();
|
||||
std::transform(j.rbegin(), j.rend(),
|
||||
@ -150,7 +150,7 @@ void from_json(const BasicJsonType& j, std::valarray<T>& l)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
l.resize(j.size());
|
||||
std::transform(j.begin(), j.end(), std::begin(l),
|
||||
@ -241,8 +241,7 @@ void())
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " +
|
||||
std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
|
||||
from_json_array_impl(j, arr, priority_tag<3> {});
|
||||
@ -253,7 +252,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
|
||||
bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
|
||||
@ -265,7 +264,7 @@ void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
|
||||
ConstructibleObjectType ret;
|
||||
@ -319,7 +318,7 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
|
||||
}
|
||||
|
||||
default:
|
||||
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,14 +347,14 @@ void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>&
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
m.clear();
|
||||
for (const auto& p : j)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
|
||||
}
|
||||
m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
|
||||
}
|
||||
@ -368,14 +367,14 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
|
||||
}
|
||||
m.clear();
|
||||
for (const auto& p : j)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
|
||||
}
|
||||
m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
|
||||
}
|
||||
|
@ -132,6 +132,7 @@ struct external_constructor<value_t::array>
|
||||
{
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = arr;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -140,6 +141,7 @@ struct external_constructor<value_t::array>
|
||||
{
|
||||
j.m_type = value_t::array;
|
||||
j.m_value = std::move(arr);
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -152,6 +154,7 @@ struct external_constructor<value_t::array>
|
||||
using std::end;
|
||||
j.m_type = value_t::array;
|
||||
j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -164,6 +167,7 @@ struct external_constructor<value_t::array>
|
||||
for (const bool x : arr)
|
||||
{
|
||||
j.m_value.array->push_back(x);
|
||||
j.set_parent(j.m_value.array->back());
|
||||
}
|
||||
j.assert_invariant();
|
||||
}
|
||||
@ -179,6 +183,7 @@ struct external_constructor<value_t::array>
|
||||
{
|
||||
std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
|
||||
}
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
@ -191,6 +196,7 @@ struct external_constructor<value_t::object>
|
||||
{
|
||||
j.m_type = value_t::object;
|
||||
j.m_value = obj;
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -199,6 +205,7 @@ struct external_constructor<value_t::object>
|
||||
{
|
||||
j.m_type = value_t::object;
|
||||
j.m_value = std::move(obj);
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
|
||||
@ -211,6 +218,7 @@ struct external_constructor<value_t::object>
|
||||
|
||||
j.m_type = value_t::object;
|
||||
j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
|
||||
j.set_parents();
|
||||
j.assert_invariant();
|
||||
}
|
||||
};
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <stdexcept> // runtime_error
|
||||
#include <string> // to_string
|
||||
|
||||
#include <nlohmann/detail/value_t.hpp>
|
||||
#include <nlohmann/detail/string_escape.hpp>
|
||||
#include <nlohmann/detail/input/position_t.hpp>
|
||||
#include <nlohmann/detail/macro_scope.hpp>
|
||||
|
||||
@ -65,6 +67,61 @@ class exception : public std::exception
|
||||
return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
|
||||
}
|
||||
|
||||
template<typename BasicJsonType>
|
||||
static std::string diagnostics(const BasicJsonType& leaf_element)
|
||||
{
|
||||
#if JSON_DIAGNOSTICS
|
||||
std::vector<std::string> tokens;
|
||||
for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
|
||||
{
|
||||
switch (current->m_parent->type())
|
||||
{
|
||||
case value_t::array:
|
||||
{
|
||||
for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
|
||||
{
|
||||
if (¤t->m_parent->m_value.array->operator[](i) == current)
|
||||
{
|
||||
tokens.emplace_back(std::to_string(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::object:
|
||||
{
|
||||
for (const auto& element : *current->m_parent->m_value.object)
|
||||
{
|
||||
if (&element.second == current)
|
||||
{
|
||||
tokens.emplace_back(element.first.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: // LCOV_EXCL_LINE
|
||||
break; // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
|
||||
if (tokens.empty())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
|
||||
[](const std::string & a, const std::string & b)
|
||||
{
|
||||
return a + "/" + detail::escape(b);
|
||||
}) + ") ";
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
/// an exception object as storage for error messages
|
||||
std::runtime_error m;
|
||||
@ -127,18 +184,20 @@ class parse_error : public exception
|
||||
@param[in] what_arg the explanatory string
|
||||
@return parse_error object
|
||||
*/
|
||||
static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
|
||||
template<typename BasicJsonType>
|
||||
static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
|
||||
{
|
||||
std::string w = exception::name("parse_error", id_) + "parse error" +
|
||||
position_string(pos) + ": " + what_arg;
|
||||
position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
|
||||
return parse_error(id_, pos.chars_read_total, w.c_str());
|
||||
}
|
||||
|
||||
static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
|
||||
template<typename BasicJsonType>
|
||||
static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
|
||||
{
|
||||
std::string w = exception::name("parse_error", id_) + "parse error" +
|
||||
(byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
|
||||
": " + what_arg;
|
||||
": " + exception::diagnostics(context) + what_arg;
|
||||
return parse_error(id_, byte_, w.c_str());
|
||||
}
|
||||
|
||||
@ -204,9 +263,10 @@ caught.,invalid_iterator}
|
||||
class invalid_iterator : public exception
|
||||
{
|
||||
public:
|
||||
static invalid_iterator create(int id_, const std::string& what_arg)
|
||||
template<typename BasicJsonType>
|
||||
static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
|
||||
{
|
||||
std::string w = exception::name("invalid_iterator", id_) + what_arg;
|
||||
std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
|
||||
return invalid_iterator(id_, w.c_str());
|
||||
}
|
||||
|
||||
@ -258,9 +318,10 @@ caught.,type_error}
|
||||
class type_error : public exception
|
||||
{
|
||||
public:
|
||||
static type_error create(int id_, const std::string& what_arg)
|
||||
template<typename BasicJsonType>
|
||||
static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
|
||||
{
|
||||
std::string w = exception::name("type_error", id_) + what_arg;
|
||||
std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
|
||||
return type_error(id_, w.c_str());
|
||||
}
|
||||
|
||||
@ -305,9 +366,10 @@ caught.,out_of_range}
|
||||
class out_of_range : public exception
|
||||
{
|
||||
public:
|
||||
static out_of_range create(int id_, const std::string& what_arg)
|
||||
template<typename BasicJsonType>
|
||||
static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
|
||||
{
|
||||
std::string w = exception::name("out_of_range", id_) + what_arg;
|
||||
std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
|
||||
return out_of_range(id_, w.c_str());
|
||||
}
|
||||
|
||||
@ -343,9 +405,10 @@ caught.,other_error}
|
||||
class other_error : public exception
|
||||
{
|
||||
public:
|
||||
static other_error create(int id_, const std::string& what_arg)
|
||||
template<typename BasicJsonType>
|
||||
static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
|
||||
{
|
||||
std::string w = exception::name("other_error", id_) + what_arg;
|
||||
std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
|
||||
return other_error(id_, w.c_str());
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ class binary_reader
|
||||
if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
|
||||
{
|
||||
return sax->parse_error(chars_read, get_token_string(),
|
||||
parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
|
||||
parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ class binary_reader
|
||||
if (JSON_HEDLEY_UNLIKELY(len < 1))
|
||||
{
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"), BasicJsonType()));
|
||||
}
|
||||
|
||||
return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
|
||||
@ -234,7 +234,7 @@ class binary_reader
|
||||
if (JSON_HEDLEY_UNLIKELY(len < 0))
|
||||
{
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary"), BasicJsonType()));
|
||||
}
|
||||
|
||||
// All BSON binary values have a subtype
|
||||
@ -316,7 +316,7 @@ class binary_reader
|
||||
{
|
||||
std::array<char, 3> cr{{}};
|
||||
(std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
|
||||
return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data())));
|
||||
return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -716,7 +716,7 @@ class binary_reader
|
||||
case cbor_tag_handler_t::error:
|
||||
{
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
|
||||
}
|
||||
|
||||
case cbor_tag_handler_t::ignore:
|
||||
@ -831,7 +831,7 @@ class binary_reader
|
||||
default: // anything else (0xFF is handled inside the other types)
|
||||
{
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -926,7 +926,7 @@ class binary_reader
|
||||
default:
|
||||
{
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string"), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1025,7 +1025,7 @@ class binary_reader
|
||||
default:
|
||||
{
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary"), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1492,7 +1492,7 @@ class binary_reader
|
||||
default: // anything else
|
||||
{
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1574,7 +1574,7 @@ class binary_reader
|
||||
default:
|
||||
{
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string"), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1824,7 +1824,7 @@ class binary_reader
|
||||
|
||||
default:
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1894,7 +1894,7 @@ class binary_reader
|
||||
default:
|
||||
{
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1932,7 +1932,7 @@ class binary_reader
|
||||
return false;
|
||||
}
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size"), BasicJsonType()));
|
||||
}
|
||||
|
||||
return get_ubjson_size_value(result.first);
|
||||
@ -2022,7 +2022,7 @@ class binary_reader
|
||||
if (JSON_HEDLEY_UNLIKELY(current > 127))
|
||||
{
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char"), BasicJsonType()));
|
||||
}
|
||||
string_t s(1, static_cast<typename string_t::value_type>(current));
|
||||
return sax->string(s);
|
||||
@ -2043,7 +2043,7 @@ class binary_reader
|
||||
default: // anything else
|
||||
{
|
||||
auto last_token = get_token_string();
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
|
||||
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2221,7 +2221,7 @@ class binary_reader
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
|
||||
{
|
||||
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));
|
||||
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
|
||||
}
|
||||
|
||||
switch (result_number)
|
||||
@ -2233,7 +2233,7 @@ class binary_reader
|
||||
case token_type::value_float:
|
||||
return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
|
||||
default:
|
||||
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));
|
||||
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2389,7 +2389,7 @@ class binary_reader
|
||||
if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
|
||||
{
|
||||
return sax->parse_error(chars_read, "<end of file>",
|
||||
parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
|
||||
parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -219,8 +219,7 @@ class json_sax_dom_parser
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
|
||||
{
|
||||
JSON_THROW(out_of_range::create(408,
|
||||
"excessive object size: " + std::to_string(len)));
|
||||
JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -235,6 +234,7 @@ class json_sax_dom_parser
|
||||
|
||||
bool end_object()
|
||||
{
|
||||
ref_stack.back()->set_parents();
|
||||
ref_stack.pop_back();
|
||||
return true;
|
||||
}
|
||||
@ -245,8 +245,7 @@ class json_sax_dom_parser
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
|
||||
{
|
||||
JSON_THROW(out_of_range::create(408,
|
||||
"excessive array size: " + std::to_string(len)));
|
||||
JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -254,6 +253,7 @@ class json_sax_dom_parser
|
||||
|
||||
bool end_array()
|
||||
{
|
||||
ref_stack.back()->set_parents();
|
||||
ref_stack.pop_back();
|
||||
return true;
|
||||
}
|
||||
@ -400,7 +400,7 @@ class json_sax_dom_callback_parser
|
||||
// check object limit
|
||||
if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
|
||||
{
|
||||
JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
|
||||
JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -425,10 +425,17 @@ class json_sax_dom_callback_parser
|
||||
|
||||
bool end_object()
|
||||
{
|
||||
if (ref_stack.back() && !callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
|
||||
if (ref_stack.back())
|
||||
{
|
||||
// discard object
|
||||
*ref_stack.back() = discarded;
|
||||
if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
|
||||
{
|
||||
// discard object
|
||||
*ref_stack.back() = discarded;
|
||||
}
|
||||
else
|
||||
{
|
||||
ref_stack.back()->set_parents();
|
||||
}
|
||||
}
|
||||
|
||||
JSON_ASSERT(!ref_stack.empty());
|
||||
@ -463,7 +470,7 @@ class json_sax_dom_callback_parser
|
||||
// check array limit
|
||||
if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
|
||||
{
|
||||
JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
|
||||
JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -476,7 +483,11 @@ class json_sax_dom_callback_parser
|
||||
if (ref_stack.back())
|
||||
{
|
||||
keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
|
||||
if (!keep)
|
||||
if (keep)
|
||||
{
|
||||
ref_stack.back()->set_parents();
|
||||
}
|
||||
else
|
||||
{
|
||||
// discard array
|
||||
*ref_stack.back() = discarded;
|
||||
@ -574,7 +585,7 @@ class json_sax_dom_callback_parser
|
||||
// array
|
||||
if (ref_stack.back()->is_array())
|
||||
{
|
||||
ref_stack.back()->m_value.array->push_back(std::move(value));
|
||||
ref_stack.back()->m_value.array->emplace_back(std::move(value));
|
||||
return {true, &(ref_stack.back()->m_value.array->back())};
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,6 @@ class parser
|
||||
{
|
||||
json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
|
||||
sax_parse_internal(&sdp);
|
||||
result.assert_invariant();
|
||||
|
||||
// in strict mode, input must be completely read
|
||||
if (strict && (get_token() != token_type::end_of_input))
|
||||
@ -96,7 +95,7 @@ class parser
|
||||
sdp.parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::end_of_input, "value")));
|
||||
exception_message(token_type::end_of_input, "value"), BasicJsonType()));
|
||||
}
|
||||
|
||||
// in case of an error, return discarded value
|
||||
@ -117,15 +116,13 @@ class parser
|
||||
{
|
||||
json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
|
||||
sax_parse_internal(&sdp);
|
||||
result.assert_invariant();
|
||||
|
||||
// in strict mode, input must be completely read
|
||||
if (strict && (get_token() != token_type::end_of_input))
|
||||
{
|
||||
sdp.parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::end_of_input, "value")));
|
||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
|
||||
}
|
||||
|
||||
// in case of an error, return discarded value
|
||||
@ -135,6 +132,8 @@ class parser
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
result.assert_invariant();
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -161,8 +160,7 @@ class parser
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::end_of_input, "value")));
|
||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -208,8 +206,7 @@ class parser
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::value_string, "object key")));
|
||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
|
||||
}
|
||||
if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
|
||||
{
|
||||
@ -221,8 +218,7 @@ class parser
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::name_separator, "object separator")));
|
||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
|
||||
}
|
||||
|
||||
// remember we are now inside an object
|
||||
@ -265,7 +261,7 @@ class parser
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
|
||||
out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
|
||||
}
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
|
||||
@ -335,16 +331,14 @@ class parser
|
||||
// using "uninitialized" to avoid "expected" message
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::uninitialized, "value")));
|
||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
|
||||
}
|
||||
|
||||
default: // the last token was unexpected
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::literal_or_value, "value")));
|
||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -390,8 +384,7 @@ class parser
|
||||
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::end_array, "array")));
|
||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
|
||||
}
|
||||
|
||||
// states.back() is false -> object
|
||||
@ -404,8 +397,7 @@ class parser
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::value_string, "object key")));
|
||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
|
||||
}
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
|
||||
@ -418,8 +410,7 @@ class parser
|
||||
{
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::name_separator, "object separator")));
|
||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
|
||||
}
|
||||
|
||||
// parse values
|
||||
@ -447,8 +438,7 @@ class parser
|
||||
|
||||
return sax->parse_error(m_lexer.get_position(),
|
||||
m_lexer.get_token_string(),
|
||||
parse_error::create(101, m_lexer.get_position(),
|
||||
exception_message(token_type::end_object, "object")));
|
||||
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,7 @@ class iter_impl
|
||||
}
|
||||
|
||||
case value_t::null:
|
||||
JSON_THROW(invalid_iterator::create(214, "cannot get value"));
|
||||
JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
|
||||
|
||||
default:
|
||||
{
|
||||
@ -266,7 +266,7 @@ class iter_impl
|
||||
return *m_object;
|
||||
}
|
||||
|
||||
JSON_THROW(invalid_iterator::create(214, "cannot get value"));
|
||||
JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -300,7 +300,7 @@ class iter_impl
|
||||
return m_object;
|
||||
}
|
||||
|
||||
JSON_THROW(invalid_iterator::create(214, "cannot get value"));
|
||||
JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -401,7 +401,7 @@ class iter_impl
|
||||
// if objects are not the same, the comparison is undefined
|
||||
if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
|
||||
JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
|
||||
}
|
||||
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
@ -438,7 +438,7 @@ class iter_impl
|
||||
// if objects are not the same, the comparison is undefined
|
||||
if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
|
||||
JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
|
||||
}
|
||||
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
@ -446,7 +446,7 @@ class iter_impl
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
|
||||
JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
|
||||
|
||||
case value_t::array:
|
||||
return (m_it.array_iterator < other.m_it.array_iterator);
|
||||
@ -494,7 +494,7 @@ class iter_impl
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
|
||||
JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
@ -565,7 +565,7 @@ class iter_impl
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
|
||||
JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
|
||||
|
||||
case value_t::array:
|
||||
return m_it.array_iterator - other.m_it.array_iterator;
|
||||
@ -586,13 +586,13 @@ class iter_impl
|
||||
switch (m_object->m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
|
||||
JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
|
||||
|
||||
case value_t::array:
|
||||
return *std::next(m_it.array_iterator, n);
|
||||
|
||||
case value_t::null:
|
||||
JSON_THROW(invalid_iterator::create(214, "cannot get value"));
|
||||
JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
|
||||
|
||||
default:
|
||||
{
|
||||
@ -601,7 +601,7 @@ class iter_impl
|
||||
return *m_object;
|
||||
}
|
||||
|
||||
JSON_THROW(invalid_iterator::create(214, "cannot get value"));
|
||||
JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -619,7 +619,7 @@ class iter_impl
|
||||
return m_it.object_iterator->first;
|
||||
}
|
||||
|
||||
JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
|
||||
JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <nlohmann/detail/exceptions.hpp>
|
||||
#include <nlohmann/detail/macro_scope.hpp>
|
||||
#include <nlohmann/detail/string_escape.hpp>
|
||||
#include <nlohmann/detail/value_t.hpp>
|
||||
|
||||
namespace nlohmann
|
||||
@ -67,7 +68,7 @@ class json_pointer
|
||||
std::string{},
|
||||
[](const std::string & a, const std::string & b)
|
||||
{
|
||||
return a + "/" + escape(b);
|
||||
return a + "/" + detail::escape(b);
|
||||
});
|
||||
}
|
||||
|
||||
@ -247,7 +248,7 @@ class json_pointer
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(empty()))
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
|
||||
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
|
||||
}
|
||||
|
||||
reference_tokens.pop_back();
|
||||
@ -271,7 +272,7 @@ class json_pointer
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(empty()))
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
|
||||
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
|
||||
}
|
||||
|
||||
return reference_tokens.back();
|
||||
@ -337,15 +338,13 @@ class json_pointer
|
||||
// error condition (cf. RFC 6901, Sect. 4)
|
||||
if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
|
||||
{
|
||||
JSON_THROW(detail::parse_error::create(106, 0,
|
||||
"array index '" + s +
|
||||
"' must not begin with '0'"));
|
||||
JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
|
||||
}
|
||||
|
||||
// error condition (cf. RFC 6901, Sect. 4)
|
||||
if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
|
||||
{
|
||||
JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));
|
||||
JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
|
||||
}
|
||||
|
||||
std::size_t processed_chars = 0;
|
||||
@ -356,20 +355,20 @@ class json_pointer
|
||||
}
|
||||
JSON_CATCH(std::out_of_range&)
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
|
||||
}
|
||||
|
||||
// check if the string was completely read
|
||||
if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
|
||||
}
|
||||
|
||||
// only triggered on special platforms (like 32bit), see also
|
||||
// https://github.com/nlohmann/json/pull/2203
|
||||
if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE
|
||||
JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
return static_cast<size_type>(res);
|
||||
@ -380,7 +379,7 @@ class json_pointer
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(empty()))
|
||||
{
|
||||
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
|
||||
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
|
||||
}
|
||||
|
||||
json_pointer result = *this;
|
||||
@ -443,7 +442,7 @@ class json_pointer
|
||||
single value; that is, with an empty list of reference tokens.
|
||||
*/
|
||||
default:
|
||||
JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
|
||||
JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
|
||||
}
|
||||
}
|
||||
|
||||
@ -515,7 +514,7 @@ class json_pointer
|
||||
}
|
||||
|
||||
default:
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -548,7 +547,7 @@ class json_pointer
|
||||
// "-" always fails the range check
|
||||
JSON_THROW(detail::out_of_range::create(402,
|
||||
"array index '-' (" + std::to_string(ptr->m_value.array->size()) +
|
||||
") is out of range"));
|
||||
") is out of range", *ptr));
|
||||
}
|
||||
|
||||
// note: at performs range check
|
||||
@ -557,7 +556,7 @@ class json_pointer
|
||||
}
|
||||
|
||||
default:
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -595,9 +594,7 @@ class json_pointer
|
||||
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
|
||||
{
|
||||
// "-" cannot be used for const access
|
||||
JSON_THROW(detail::out_of_range::create(402,
|
||||
"array index '-' (" + std::to_string(ptr->m_value.array->size()) +
|
||||
") is out of range"));
|
||||
JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
|
||||
}
|
||||
|
||||
// use unchecked array access
|
||||
@ -606,7 +603,7 @@ class json_pointer
|
||||
}
|
||||
|
||||
default:
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -639,7 +636,7 @@ class json_pointer
|
||||
// "-" always fails the range check
|
||||
JSON_THROW(detail::out_of_range::create(402,
|
||||
"array index '-' (" + std::to_string(ptr->m_value.array->size()) +
|
||||
") is out of range"));
|
||||
") is out of range", *ptr));
|
||||
}
|
||||
|
||||
// note: at performs range check
|
||||
@ -648,7 +645,7 @@ class json_pointer
|
||||
}
|
||||
|
||||
default:
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
|
||||
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -752,9 +749,7 @@ class json_pointer
|
||||
// check if nonempty reference string begins with slash
|
||||
if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
|
||||
{
|
||||
JSON_THROW(detail::parse_error::create(107, 1,
|
||||
"JSON pointer must be empty or begin with '/' - was: '" +
|
||||
reference_string + "'"));
|
||||
JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
|
||||
}
|
||||
|
||||
// extract the reference tokens:
|
||||
@ -789,58 +784,18 @@ class json_pointer
|
||||
(reference_token[pos + 1] != '0' &&
|
||||
reference_token[pos + 1] != '1')))
|
||||
{
|
||||
JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
|
||||
JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
|
||||
}
|
||||
}
|
||||
|
||||
// finally, store the reference token
|
||||
unescape(reference_token);
|
||||
detail::unescape(reference_token);
|
||||
result.push_back(reference_token);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief replace all occurrences of a substring by another string
|
||||
|
||||
@param[in,out] s the string to manipulate; changed so that all
|
||||
occurrences of @a f are replaced with @a t
|
||||
@param[in] f the substring to replace with @a t
|
||||
@param[in] t the string to replace @a f
|
||||
|
||||
@pre The search string @a f must not be empty. **This precondition is
|
||||
enforced with an assertion.**
|
||||
|
||||
@since version 2.0.0
|
||||
*/
|
||||
static void replace_substring(std::string& s, const std::string& f,
|
||||
const std::string& t)
|
||||
{
|
||||
JSON_ASSERT(!f.empty());
|
||||
for (auto pos = s.find(f); // find first occurrence of f
|
||||
pos != std::string::npos; // make sure f was found
|
||||
s.replace(pos, f.size(), t), // replace with t, and
|
||||
pos = s.find(f, pos + t.size())) // find next occurrence of f
|
||||
{}
|
||||
}
|
||||
|
||||
JSON_PRIVATE_UNLESS_TESTED:
|
||||
/// escape "~" to "~0" and "/" to "~1"
|
||||
static std::string escape(std::string s)
|
||||
{
|
||||
replace_substring(s, "~", "~0");
|
||||
replace_substring(s, "/", "~1");
|
||||
return s;
|
||||
}
|
||||
|
||||
/// unescape "~1" to tilde and "~0" to slash (order is important!)
|
||||
static void unescape(std::string& s)
|
||||
{
|
||||
replace_substring(s, "~1", "/");
|
||||
replace_substring(s, "~0", "~");
|
||||
}
|
||||
|
||||
private:
|
||||
/*!
|
||||
@param[in] reference_string the reference string to the current value
|
||||
@ -886,7 +841,7 @@ class json_pointer
|
||||
// iterate object and use keys as reference string
|
||||
for (const auto& element : *value.m_value.object)
|
||||
{
|
||||
flatten(reference_string + "/" + escape(element.first), element.second, result);
|
||||
flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -916,7 +871,7 @@ class json_pointer
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
|
||||
{
|
||||
JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
|
||||
JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
|
||||
}
|
||||
|
||||
BasicJsonType result;
|
||||
@ -926,7 +881,7 @@ class json_pointer
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
|
||||
{
|
||||
JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
|
||||
JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
|
||||
}
|
||||
|
||||
// assign value to reference pointed to by JSON pointer; Note that if
|
||||
|
@ -57,7 +57,7 @@ class binary_writer
|
||||
|
||||
default:
|
||||
{
|
||||
JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -901,13 +901,12 @@ class binary_writer
|
||||
@return The size of a BSON document entry header, including the id marker
|
||||
and the entry name size (and its null-terminator).
|
||||
*/
|
||||
static std::size_t calc_bson_entry_header_size(const string_t& name)
|
||||
static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
|
||||
{
|
||||
const auto it = name.find(static_cast<typename string_t::value_type>(0));
|
||||
if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
|
||||
{
|
||||
JSON_THROW(out_of_range::create(409,
|
||||
"BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
|
||||
JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
|
||||
}
|
||||
|
||||
return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
|
||||
@ -1017,21 +1016,21 @@ class binary_writer
|
||||
@brief Writes a BSON element with key @a name and unsigned @a value
|
||||
*/
|
||||
void write_bson_unsigned(const string_t& name,
|
||||
const std::uint64_t value)
|
||||
const BasicJsonType& j)
|
||||
{
|
||||
if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
|
||||
if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
|
||||
{
|
||||
write_bson_entry_header(name, 0x10 /* int32 */);
|
||||
write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
|
||||
write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
|
||||
}
|
||||
else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
|
||||
else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
|
||||
{
|
||||
write_bson_entry_header(name, 0x12 /* int64 */);
|
||||
write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
|
||||
write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
|
||||
JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BSON as it does not fit int64", j));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1108,7 +1107,7 @@ class binary_writer
|
||||
static std::size_t calc_bson_element_size(const string_t& name,
|
||||
const BasicJsonType& j)
|
||||
{
|
||||
const auto header_size = calc_bson_entry_header_size(name);
|
||||
const auto header_size = calc_bson_entry_header_size(name, j);
|
||||
switch (j.type())
|
||||
{
|
||||
case value_t::object:
|
||||
@ -1177,7 +1176,7 @@ class binary_writer
|
||||
return write_bson_integer(name, j.m_value.number_integer);
|
||||
|
||||
case value_t::number_unsigned:
|
||||
return write_bson_unsigned(name, j.m_value.number_unsigned);
|
||||
return write_bson_unsigned(name, j);
|
||||
|
||||
case value_t::string:
|
||||
return write_bson_string(name, *j.m_value.string);
|
||||
|
@ -499,7 +499,7 @@ class serializer
|
||||
{
|
||||
std::string sn(3, '\0');
|
||||
(std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
|
||||
JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
|
||||
JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
|
||||
}
|
||||
|
||||
case error_handler_t::ignore:
|
||||
@ -593,7 +593,7 @@ class serializer
|
||||
{
|
||||
std::string sn(3, '\0');
|
||||
(std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
|
||||
JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
|
||||
JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
|
||||
}
|
||||
|
||||
case error_handler_t::ignore:
|
||||
|
63
include/nlohmann/detail/string_escape.hpp
Normal file
63
include/nlohmann/detail/string_escape.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <nlohmann/detail/macro_scope.hpp>
|
||||
|
||||
namespace nlohmann
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
/*!
|
||||
@brief replace all occurrences of a substring by another string
|
||||
|
||||
@param[in,out] s the string to manipulate; changed so that all
|
||||
occurrences of @a f are replaced with @a t
|
||||
@param[in] f the substring to replace with @a t
|
||||
@param[in] t the string to replace @a f
|
||||
|
||||
@pre The search string @a f must not be empty. **This precondition is
|
||||
enforced with an assertion.**
|
||||
|
||||
@since version 2.0.0
|
||||
*/
|
||||
inline void replace_substring(std::string& s, const std::string& f,
|
||||
const std::string& t)
|
||||
{
|
||||
JSON_ASSERT(!f.empty());
|
||||
for (auto pos = s.find(f); // find first occurrence of f
|
||||
pos != std::string::npos; // make sure f was found
|
||||
s.replace(pos, f.size(), t), // replace with t, and
|
||||
pos = s.find(f, pos + t.size())) // find next occurrence of f
|
||||
{}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief string escaping as described in RFC 6901 (Sect. 4)
|
||||
* @param[in] s string to escape
|
||||
* @return escaped string
|
||||
*
|
||||
* Note the order of escaping "~" to "~0" and "/" to "~1" is important.
|
||||
*/
|
||||
inline std::string escape(std::string s)
|
||||
{
|
||||
replace_substring(s, "~", "~0");
|
||||
replace_substring(s, "/", "~1");
|
||||
return s;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief string unescaping as described in RFC 6901 (Sect. 4)
|
||||
* @param[in] s string to unescape
|
||||
* @return unescaped string
|
||||
*
|
||||
* Note the order of escaping "~1" to "/" and "~0" to "~" is important.
|
||||
*/
|
||||
static void unescape(std::string& s)
|
||||
{
|
||||
replace_substring(s, "~1", "/");
|
||||
replace_substring(s, "~0", "~");
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace nlohmann
|
@ -32,7 +32,7 @@ number_float), because the library distinguishes these three types for numbers:
|
||||
@ref basic_json::number_float_t is used for floating-point numbers or to
|
||||
approximate integers which do not fit in the limits of their respective type.
|
||||
|
||||
@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
|
||||
@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON
|
||||
value with the default value for a given type
|
||||
|
||||
@since version 1.0.0
|
||||
|
@ -189,6 +189,7 @@ class basic_json
|
||||
friend class ::nlohmann::detail::json_sax_dom_parser;
|
||||
template<typename BasicJsonType>
|
||||
friend class ::nlohmann::detail::json_sax_dom_callback_parser;
|
||||
friend class ::nlohmann::detail::exception;
|
||||
|
||||
/// workaround type for MSVC
|
||||
using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
|
||||
@ -1060,7 +1061,7 @@ class basic_json
|
||||
object = nullptr; // silence warning, see #821
|
||||
if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
|
||||
{
|
||||
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1")); // LCOV_EXCL_LINE
|
||||
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1", basic_json())); // LCOV_EXCL_LINE
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1227,13 +1228,83 @@ class basic_json
|
||||
invariant. Furthermore, it has to be called each time the type of a JSON
|
||||
value is changed, because the invariant expresses a relationship between
|
||||
@a m_type and @a m_value.
|
||||
|
||||
Furthermore, the parent relation is checked for arrays and objects: If
|
||||
@a check_parents true and the value is an array or object, then the
|
||||
container's elements must have the current value as parent.
|
||||
|
||||
@param[in] check_parents whether the parent relation should be checked.
|
||||
The value is true by default and should only be set to false
|
||||
during destruction of objects when the invariant does not
|
||||
need to hold.
|
||||
*/
|
||||
void assert_invariant() const noexcept
|
||||
void assert_invariant(bool check_parents = true) const noexcept
|
||||
{
|
||||
JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
|
||||
JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
|
||||
JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
|
||||
JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
|
||||
|
||||
#if JSON_DIAGNOSTICS
|
||||
JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
|
||||
{
|
||||
return j.m_parent == this;
|
||||
}));
|
||||
#else
|
||||
static_cast<void>(check_parents);
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_parents()
|
||||
{
|
||||
#if JSON_DIAGNOSTICS
|
||||
switch (m_type)
|
||||
{
|
||||
case value_t::array:
|
||||
{
|
||||
for (auto& element : *m_value.array)
|
||||
{
|
||||
element.m_parent = this;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::object:
|
||||
{
|
||||
for (auto& element : *m_value.object)
|
||||
{
|
||||
element.second.m_parent = this;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
iterator set_parents(iterator it, typename iterator::difference_type count)
|
||||
{
|
||||
#if JSON_DIAGNOSTICS
|
||||
for (typename iterator::difference_type i = 0; i < count; ++i)
|
||||
{
|
||||
(it + i)->m_parent = this;
|
||||
}
|
||||
#else
|
||||
static_cast<void>(count);
|
||||
#endif
|
||||
return it;
|
||||
}
|
||||
|
||||
reference set_parent(reference j)
|
||||
{
|
||||
#if JSON_DIAGNOSTICS
|
||||
j.m_parent = this;
|
||||
#else
|
||||
static_cast<void>(j);
|
||||
#endif
|
||||
return j;
|
||||
}
|
||||
|
||||
public:
|
||||
@ -1450,6 +1521,7 @@ class basic_json
|
||||
std::forward<CompatibleType>(val))))
|
||||
{
|
||||
JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
|
||||
set_parents();
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -1528,6 +1600,7 @@ class basic_json
|
||||
default: // LCOV_EXCL_LINE
|
||||
JSON_ASSERT(false); // LCOV_EXCL_LINE
|
||||
}
|
||||
set_parents();
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -1629,7 +1702,7 @@ class basic_json
|
||||
// if object is wanted but impossible, throw an exception
|
||||
if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
|
||||
{
|
||||
JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
|
||||
JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1639,13 +1712,13 @@ class basic_json
|
||||
m_type = value_t::object;
|
||||
m_value = value_t::object;
|
||||
|
||||
std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
|
||||
for (auto& element_ref : init)
|
||||
{
|
||||
auto element = element_ref.moved_or_copied();
|
||||
m_value.object->emplace(
|
||||
std::move(*((*element.m_value.array)[0].m_value.string)),
|
||||
std::move((*element.m_value.array)[1]));
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1654,6 +1727,7 @@ class basic_json
|
||||
m_value.array = create<array_t>(init.begin(), init.end());
|
||||
}
|
||||
|
||||
set_parents();
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -1863,6 +1937,7 @@ class basic_json
|
||||
: m_type(value_t::array)
|
||||
{
|
||||
m_value.array = create<array_t>(cnt, val);
|
||||
set_parents();
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -1932,7 +2007,7 @@ class basic_json
|
||||
// make sure iterator fits the current value
|
||||
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
|
||||
JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
|
||||
}
|
||||
|
||||
// copy type from first iterator
|
||||
@ -1950,7 +2025,7 @@ class basic_json
|
||||
if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
|
||||
|| !last.m_it.primitive_iterator.is_end()))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
|
||||
JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2012,10 +2087,10 @@ class basic_json
|
||||
}
|
||||
|
||||
default:
|
||||
JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
|
||||
std::string(first.m_object->type_name())));
|
||||
JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
|
||||
}
|
||||
|
||||
set_parents();
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -2114,6 +2189,7 @@ class basic_json
|
||||
break;
|
||||
}
|
||||
|
||||
set_parents();
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -2148,12 +2224,13 @@ class basic_json
|
||||
m_value(std::move(other.m_value))
|
||||
{
|
||||
// check that passed value is valid
|
||||
other.assert_invariant();
|
||||
other.assert_invariant(false);
|
||||
|
||||
// invalidate payload
|
||||
other.m_type = value_t::null;
|
||||
other.m_value = {};
|
||||
|
||||
set_parents();
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -2194,6 +2271,7 @@ class basic_json
|
||||
swap(m_type, other.m_type);
|
||||
swap(m_value, other.m_value);
|
||||
|
||||
set_parents();
|
||||
assert_invariant();
|
||||
return *this;
|
||||
}
|
||||
@ -2215,7 +2293,7 @@ class basic_json
|
||||
*/
|
||||
~basic_json() noexcept
|
||||
{
|
||||
assert_invariant();
|
||||
assert_invariant(false);
|
||||
m_value.destroy(m_type);
|
||||
}
|
||||
|
||||
@ -2708,7 +2786,7 @@ class basic_json
|
||||
return m_value.boolean;
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
/// get a pointer to the value (object)
|
||||
@ -2829,7 +2907,7 @@ class basic_json
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
|
||||
JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
|
||||
}
|
||||
|
||||
public:
|
||||
@ -3257,7 +3335,7 @@ class basic_json
|
||||
{
|
||||
if (!is_binary())
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
return *get_ptr<binary_t*>();
|
||||
@ -3268,7 +3346,7 @@ class basic_json
|
||||
{
|
||||
if (!is_binary())
|
||||
{
|
||||
JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
return *get_ptr<const binary_t*>();
|
||||
@ -3318,17 +3396,17 @@ class basic_json
|
||||
{
|
||||
JSON_TRY
|
||||
{
|
||||
return m_value.array->at(idx);
|
||||
return set_parent(m_value.array->at(idx));
|
||||
}
|
||||
JSON_CATCH (std::out_of_range&)
|
||||
{
|
||||
// create better exception explanation
|
||||
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
|
||||
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3370,12 +3448,12 @@ class basic_json
|
||||
JSON_CATCH (std::out_of_range&)
|
||||
{
|
||||
// create better exception explanation
|
||||
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
|
||||
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3416,17 +3494,17 @@ class basic_json
|
||||
{
|
||||
JSON_TRY
|
||||
{
|
||||
return m_value.object->at(key);
|
||||
return set_parent(m_value.object->at(key));
|
||||
}
|
||||
JSON_CATCH (std::out_of_range&)
|
||||
{
|
||||
// create better exception explanation
|
||||
JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
|
||||
JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3472,12 +3550,12 @@ class basic_json
|
||||
JSON_CATCH (std::out_of_range&)
|
||||
{
|
||||
// create better exception explanation
|
||||
JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
|
||||
JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3522,15 +3600,22 @@ class basic_json
|
||||
// fill up array with null values if given idx is outside range
|
||||
if (idx >= m_value.array->size())
|
||||
{
|
||||
m_value.array->insert(m_value.array->end(),
|
||||
idx - m_value.array->size() + 1,
|
||||
basic_json());
|
||||
#if JSON_DIAGNOSTICS
|
||||
// remember array size before resizing
|
||||
const auto previous_size = m_value.array->size();
|
||||
#endif
|
||||
m_value.array->resize(idx + 1);
|
||||
|
||||
#if JSON_DIAGNOSTICS
|
||||
// set parent for values added above
|
||||
set_parents(begin() + static_cast<typename iterator::difference_type>(previous_size), static_cast<typename iterator::difference_type>(idx + 1 - previous_size));
|
||||
#endif
|
||||
}
|
||||
|
||||
return m_value.array->operator[](idx);
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3560,7 +3645,7 @@ class basic_json
|
||||
return m_value.array->operator[](idx);
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3603,10 +3688,10 @@ class basic_json
|
||||
// operator[] only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
return m_value.object->operator[](key);
|
||||
return set_parent(m_value.object->operator[](key));
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3648,7 +3733,7 @@ class basic_json
|
||||
return m_value.object->find(key)->second;
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3693,10 +3778,10 @@ class basic_json
|
||||
// at only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
return m_value.object->operator[](key);
|
||||
return set_parent(m_value.object->operator[](key));
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3740,7 +3825,7 @@ class basic_json
|
||||
return m_value.object->find(key)->second;
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3812,7 +3897,7 @@ class basic_json
|
||||
return default_value;
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3885,7 +3970,7 @@ class basic_json
|
||||
}
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -4039,7 +4124,7 @@ class basic_json
|
||||
// make sure iterator fits the current value
|
||||
if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
|
||||
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
|
||||
}
|
||||
|
||||
IteratorType result = end();
|
||||
@ -4055,7 +4140,7 @@ class basic_json
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
|
||||
JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
|
||||
}
|
||||
|
||||
if (is_string())
|
||||
@ -4091,7 +4176,7 @@ class basic_json
|
||||
}
|
||||
|
||||
default:
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -4152,7 +4237,7 @@ class basic_json
|
||||
// make sure iterator fits the current value
|
||||
if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
|
||||
JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
|
||||
}
|
||||
|
||||
IteratorType result = end();
|
||||
@ -4169,7 +4254,7 @@ class basic_json
|
||||
if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
|
||||
|| !last.m_it.primitive_iterator.is_end()))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
|
||||
JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
|
||||
}
|
||||
|
||||
if (is_string())
|
||||
@ -4207,7 +4292,7 @@ class basic_json
|
||||
}
|
||||
|
||||
default:
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -4250,7 +4335,7 @@ class basic_json
|
||||
return m_value.object->erase(key);
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -4284,14 +4369,14 @@ class basic_json
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(idx >= size()))
|
||||
{
|
||||
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
|
||||
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
|
||||
}
|
||||
|
||||
m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5236,7 +5321,7 @@ class basic_json
|
||||
// push_back only works for null objects or arrays
|
||||
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
|
||||
{
|
||||
JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
// transform null object into an array
|
||||
@ -5249,6 +5334,7 @@ class basic_json
|
||||
|
||||
// add element to array (move semantics)
|
||||
m_value.array->push_back(std::move(val));
|
||||
set_parent(m_value.array->back());
|
||||
// if val is moved from, basic_json move constructor marks it null so we do not call the destructor
|
||||
}
|
||||
|
||||
@ -5271,7 +5357,7 @@ class basic_json
|
||||
// push_back only works for null objects or arrays
|
||||
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
|
||||
{
|
||||
JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
// transform null object into an array
|
||||
@ -5284,6 +5370,7 @@ class basic_json
|
||||
|
||||
// add element to array
|
||||
m_value.array->push_back(val);
|
||||
set_parent(m_value.array->back());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -5321,7 +5408,7 @@ class basic_json
|
||||
// push_back only works for null objects or objects
|
||||
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
|
||||
{
|
||||
JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
// transform null object into an object
|
||||
@ -5332,8 +5419,9 @@ class basic_json
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
// add element to array
|
||||
m_value.object->insert(val);
|
||||
// add element to object
|
||||
auto res = m_value.object->insert(val);
|
||||
set_parent(res.first->second);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -5424,7 +5512,7 @@ class basic_json
|
||||
// emplace_back only works for null objects or arrays
|
||||
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
|
||||
{
|
||||
JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
// transform null object into an array
|
||||
@ -5437,10 +5525,10 @@ class basic_json
|
||||
|
||||
// add element to array (perfect forwarding)
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
return m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||
return set_parent(m_value.array->emplace_back(std::forward<Args>(args)...));
|
||||
#else
|
||||
m_value.array->emplace_back(std::forward<Args>(args)...);
|
||||
return m_value.array->back();
|
||||
return set_parent(m_value.array->back());
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -5477,7 +5565,7 @@ class basic_json
|
||||
// emplace only works for null objects or arrays
|
||||
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
|
||||
{
|
||||
JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
// transform null object into an object
|
||||
@ -5490,6 +5578,8 @@ class basic_json
|
||||
|
||||
// add element to array (perfect forwarding)
|
||||
auto res = m_value.object->emplace(std::forward<Args>(args)...);
|
||||
set_parent(res.first->second);
|
||||
|
||||
// create result iterator and set iterator to the result of emplace
|
||||
auto it = begin();
|
||||
it.m_it.object_iterator = res.first;
|
||||
@ -5548,14 +5638,14 @@ class basic_json
|
||||
// check if iterator pos fits to this JSON value
|
||||
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
|
||||
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
|
||||
}
|
||||
|
||||
// insert to array and return iterator
|
||||
return insert_iterator(pos, val);
|
||||
return set_parents(insert_iterator(pos, val), static_cast<typename iterator::difference_type>(1));
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -5599,14 +5689,14 @@ class basic_json
|
||||
// check if iterator pos fits to this JSON value
|
||||
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
|
||||
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
|
||||
}
|
||||
|
||||
// insert to array and return iterator
|
||||
return insert_iterator(pos, cnt, val);
|
||||
return set_parents(insert_iterator(pos, cnt, val), static_cast<typename iterator::difference_type>(cnt));
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -5644,28 +5734,28 @@ class basic_json
|
||||
// insert only works for arrays
|
||||
if (JSON_HEDLEY_UNLIKELY(!is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
// check if iterator pos fits to this JSON value
|
||||
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
|
||||
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
|
||||
}
|
||||
|
||||
// check if range iterators belong to the same JSON object
|
||||
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
|
||||
JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
|
||||
}
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
|
||||
JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
|
||||
}
|
||||
|
||||
// insert to array and return iterator
|
||||
return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
|
||||
return set_parents(insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator), std::distance(first, last));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -5697,17 +5787,17 @@ class basic_json
|
||||
// insert only works for arrays
|
||||
if (JSON_HEDLEY_UNLIKELY(!is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
// check if iterator pos fits to this JSON value
|
||||
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
|
||||
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
|
||||
}
|
||||
|
||||
// insert to array and return iterator
|
||||
return insert_iterator(pos, ilist.begin(), ilist.end());
|
||||
return set_parents(insert_iterator(pos, ilist.begin(), ilist.end()), static_cast<typename iterator::difference_type>(ilist.size()));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -5738,19 +5828,19 @@ class basic_json
|
||||
// insert only works for objects
|
||||
if (JSON_HEDLEY_UNLIKELY(!is_object()))
|
||||
{
|
||||
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
// check if range iterators belong to the same JSON object
|
||||
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
|
||||
JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
|
||||
}
|
||||
|
||||
// passed iterators must belong to objects
|
||||
if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
|
||||
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
|
||||
}
|
||||
|
||||
m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
|
||||
@ -5787,11 +5877,11 @@ class basic_json
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(!is_object()))
|
||||
{
|
||||
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
|
||||
}
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
|
||||
{
|
||||
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
|
||||
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
|
||||
}
|
||||
|
||||
for (auto it = j.cbegin(); it != j.cend(); ++it)
|
||||
@ -5838,20 +5928,20 @@ class basic_json
|
||||
|
||||
if (JSON_HEDLEY_UNLIKELY(!is_object()))
|
||||
{
|
||||
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
// check if range iterators belong to the same JSON object
|
||||
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
|
||||
JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
|
||||
}
|
||||
|
||||
// passed iterators must belong to objects
|
||||
if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
|
||||
|| !last.m_object->is_object()))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
|
||||
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
|
||||
}
|
||||
|
||||
for (auto it = first; it != last; ++it)
|
||||
@ -5886,6 +5976,9 @@ class basic_json
|
||||
{
|
||||
std::swap(m_type, other.m_type);
|
||||
std::swap(m_value, other.m_value);
|
||||
|
||||
set_parents();
|
||||
other.set_parents();
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
@ -5946,7 +6039,7 @@ class basic_json
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5979,7 +6072,7 @@ class basic_json
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -6012,7 +6105,7 @@ class basic_json
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -6045,7 +6138,7 @@ class basic_json
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -6059,7 +6152,7 @@ class basic_json
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
|
||||
JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -6967,6 +7060,11 @@ class basic_json
|
||||
/// the value of the current element
|
||||
json_value m_value = {};
|
||||
|
||||
#if JSON_DIAGNOSTICS
|
||||
/// a pointer to a parent value (for debugging purposes)
|
||||
basic_json* m_parent = nullptr;
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////
|
||||
// binary serialization/deserialization //
|
||||
//////////////////////////////////////////
|
||||
@ -8263,7 +8361,7 @@ class basic_json
|
||||
if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
|
||||
{
|
||||
// avoid undefined behavior
|
||||
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
|
||||
JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
|
||||
}
|
||||
|
||||
// default case: insert add offset
|
||||
@ -8279,7 +8377,7 @@ class basic_json
|
||||
};
|
||||
|
||||
// wrapper for "remove" operation; remove value at ptr
|
||||
const auto operation_remove = [&result](json_pointer & ptr)
|
||||
const auto operation_remove = [this, &result](json_pointer & ptr)
|
||||
{
|
||||
// get reference to parent of JSON pointer ptr
|
||||
const auto last_path = ptr.back();
|
||||
@ -8297,7 +8395,7 @@ class basic_json
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
|
||||
JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
|
||||
}
|
||||
}
|
||||
else if (parent.is_array())
|
||||
@ -8310,7 +8408,7 @@ class basic_json
|
||||
// type check: top level value must be an array
|
||||
if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
|
||||
{
|
||||
JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
|
||||
JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
|
||||
}
|
||||
|
||||
// iterate and apply the operations
|
||||
@ -8330,13 +8428,13 @@ class basic_json
|
||||
// check if desired value is present
|
||||
if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
|
||||
{
|
||||
JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
|
||||
JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
|
||||
}
|
||||
|
||||
// check if result is of type string
|
||||
if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
|
||||
{
|
||||
JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
|
||||
JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
|
||||
}
|
||||
|
||||
// no error: return value
|
||||
@ -8346,7 +8444,7 @@ class basic_json
|
||||
// type check: every element of the array must be an object
|
||||
if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
|
||||
{
|
||||
JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
|
||||
JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
|
||||
}
|
||||
|
||||
// collect mandatory members
|
||||
@ -8424,7 +8522,7 @@ class basic_json
|
||||
// throw an exception if test fails
|
||||
if (JSON_HEDLEY_UNLIKELY(!success))
|
||||
{
|
||||
JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
|
||||
JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
|
||||
}
|
||||
|
||||
break;
|
||||
@ -8434,7 +8532,7 @@ class basic_json
|
||||
{
|
||||
// op must be "add", "remove", "replace", "move", "copy", or
|
||||
// "test"
|
||||
JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
|
||||
JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8550,7 +8648,7 @@ class basic_json
|
||||
for (auto it = source.cbegin(); it != source.cend(); ++it)
|
||||
{
|
||||
// escape the key name to be used in a JSON patch
|
||||
const auto key = json_pointer::escape(it.key());
|
||||
const auto key = detail::escape(it.key());
|
||||
|
||||
if (target.find(it.key()) != target.end())
|
||||
{
|
||||
@ -8574,7 +8672,7 @@ class basic_json
|
||||
if (source.find(it.key()) == source.end())
|
||||
{
|
||||
// found a key that is not in this -> add it
|
||||
const auto key = json_pointer::escape(it.key());
|
||||
const auto key = detail::escape(it.key());
|
||||
result.push_back(
|
||||
{
|
||||
{"op", "add"}, {"path", path + "/" + key},
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -110,6 +110,7 @@ set(files
|
||||
src/unit-convenience.cpp
|
||||
src/unit-conversions.cpp
|
||||
src/unit-deserialization.cpp
|
||||
src/unit-diagnostics.cpp
|
||||
src/unit-element_access1.cpp
|
||||
src/unit-element_access2.cpp
|
||||
src/unit-hash.cpp
|
||||
|
@ -101,7 +101,11 @@ TEST_CASE("BSON")
|
||||
{ std::string("en\0try", 6), true }
|
||||
};
|
||||
CHECK_THROWS_AS(json::to_bson(j), json::out_of_range&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(json::to_bson(j), "[json.exception.out_of_range.409] (/en) BSON key cannot contain code point U+0000 (at byte 2)");
|
||||
#else
|
||||
CHECK_THROWS_WITH(json::to_bson(j), "[json.exception.out_of_range.409] BSON key cannot contain code point U+0000 (at byte 2)");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("string length must be at least 1")
|
||||
@ -1235,7 +1239,11 @@ TEST_CASE("BSON numerical data")
|
||||
};
|
||||
|
||||
CHECK_THROWS_AS(json::to_bson(j), json::out_of_range&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH_STD_STR(json::to_bson(j), "[json.exception.out_of_range.407] (/entry) integer number " + std::to_string(i) + " cannot be represented by BSON as it does not fit int64");
|
||||
#else
|
||||
CHECK_THROWS_WITH_STD_STR(json::to_bson(j), "[json.exception.out_of_range.407] integer number " + std::to_string(i) + " cannot be represented by BSON as it does not fit int64");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
111
test/src/unit-diagnostics.cpp
Normal file
111
test/src/unit-diagnostics.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
#undef JSON_DIAGNOSTICS
|
||||
#endif
|
||||
|
||||
#define JSON_DIAGNOSTICS 1
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("Better diagnostics")
|
||||
{
|
||||
SECTION("empty JSON Pointer")
|
||||
{
|
||||
json j = 1;
|
||||
std::string s;
|
||||
CHECK_THROWS_WITH_AS(s = j.get<std::string>(), "[json.exception.type_error.302] type must be string, but is number", json::type_error);
|
||||
}
|
||||
|
||||
SECTION("invalid type")
|
||||
{
|
||||
json j;
|
||||
j["a"]["b"]["c"] = 1;
|
||||
std::string s;
|
||||
CHECK_THROWS_WITH_AS(s = j["a"]["b"]["c"].get<std::string>(), "[json.exception.type_error.302] (/a/b/c) type must be string, but is number", json::type_error);
|
||||
}
|
||||
|
||||
SECTION("missing key")
|
||||
{
|
||||
json j;
|
||||
j["object"]["object"] = true;
|
||||
CHECK_THROWS_WITH_AS(j["object"].at("not_found"), "[json.exception.out_of_range.403] (/object) key 'not_found' not found", json::out_of_range);
|
||||
}
|
||||
|
||||
SECTION("array index out of range")
|
||||
{
|
||||
json j;
|
||||
j["array"][4] = true;
|
||||
CHECK_THROWS_WITH_AS(j["array"].at(5), "[json.exception.out_of_range.401] (/array) array index 5 is out of range", json::out_of_range);
|
||||
}
|
||||
|
||||
SECTION("array index at wrong type")
|
||||
{
|
||||
json j;
|
||||
j["array"][4] = true;
|
||||
CHECK_THROWS_WITH_AS(j["array"][4][5], "[json.exception.type_error.305] (/array/4) cannot use operator[] with a numeric argument with boolean", json::type_error);
|
||||
}
|
||||
|
||||
SECTION("wrong iterator")
|
||||
{
|
||||
json j;
|
||||
j["array"] = json::array();
|
||||
CHECK_THROWS_WITH_AS(j["array"].erase(j.begin()), "[json.exception.invalid_iterator.202] (/array) iterator does not fit current value", json::invalid_iterator);
|
||||
}
|
||||
|
||||
SECTION("JSON Pointer escaping")
|
||||
{
|
||||
json j;
|
||||
j["a/b"]["m~n"] = 1;
|
||||
std::string s;
|
||||
CHECK_THROWS_WITH_AS(s = j["a/b"]["m~n"].get<std::string>(), "[json.exception.type_error.302] (/a~1b/m~0n) type must be string, but is number", json::type_error);
|
||||
}
|
||||
|
||||
SECTION("Parse error")
|
||||
{
|
||||
CHECK_THROWS_WITH_AS(json::parse(""), "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error);
|
||||
}
|
||||
|
||||
SECTION("Regression test for https://github.com/nlohmann/json/pull/2562#pullrequestreview-574858448")
|
||||
{
|
||||
CHECK_THROWS_WITH_AS(json({"0", "0"})[1].get<int>(), "[json.exception.type_error.302] (/1) type must be number, but is string", json::type_error);
|
||||
CHECK_THROWS_WITH_AS(json({"0", "1"})[1].get<int>(), "[json.exception.type_error.302] (/1) type must be number, but is string", json::type_error);
|
||||
}
|
||||
|
||||
SECTION("Regression test for https://github.com/nlohmann/json/pull/2562/files/380a613f2b5d32425021129cd1f371ddcfd54ddf#r563259793")
|
||||
{
|
||||
json j;
|
||||
j["/foo"] = {1, 2, 3};
|
||||
CHECK_THROWS_WITH_AS(j.unflatten(), "[json.exception.type_error.315] (/~1foo) values in object must be primitive", json::type_error);
|
||||
}
|
||||
}
|
@ -90,6 +90,16 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_AS(it1_c < it2_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it2_c < it3_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it1_c < it3_c, json::invalid_iterator&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(it1 < it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 < it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 < it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 < it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c < it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c < it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c < it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c < it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
#else
|
||||
CHECK_THROWS_WITH(it1 < it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 < it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
@ -98,6 +108,7 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_WITH(it1_c < it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -124,6 +135,16 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_AS(it1_c <= it2_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it2_c <= it3_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it1_c <= it3_c, json::invalid_iterator&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(it1 <= it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 <= it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 <= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 <= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c <= it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c <= it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c <= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c <= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
#else
|
||||
CHECK_THROWS_WITH(it1 <= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 <= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
@ -132,6 +153,7 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_WITH(it1_c <= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -159,6 +181,16 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_AS(it1_c > it2_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it2_c > it3_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it1_c > it3_c, json::invalid_iterator&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(it1 > it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 > it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 > it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 > it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c > it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c > it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c > it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c > it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
#else
|
||||
CHECK_THROWS_WITH(it1 > it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 > it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
@ -167,6 +199,7 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_WITH(it1_c > it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -194,6 +227,16 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_AS(it1_c >= it2_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it2_c >= it3_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it1_c >= it3_c, json::invalid_iterator&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(it1 >= it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 >= it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 >= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 >= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c >= it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c >= it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c >= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c >= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
#else
|
||||
CHECK_THROWS_WITH(it1 >= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 >= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
@ -202,6 +245,7 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_WITH(it1_c >= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -227,13 +271,16 @@ TEST_CASE("iterators 2")
|
||||
{
|
||||
CHECK_THROWS_AS(j.begin() == k.begin(), json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(j.cbegin() == k.cbegin(), json::invalid_iterator&);
|
||||
CHECK_THROWS_WITH(j.begin() == k.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
CHECK_THROWS_WITH(j.cbegin() == k.cbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
|
||||
CHECK_THROWS_AS(j.begin() < k.begin(), json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(j.cbegin() < k.cbegin(), json::invalid_iterator&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
// the output differs in each loop, so we cannot fix a string for the expected exception
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.begin() == k.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
CHECK_THROWS_WITH(j.cbegin() == k.cbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
CHECK_THROWS_WITH(j.begin() < k.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
CHECK_THROWS_WITH(j.cbegin() < k.cbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -525,6 +572,16 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_AS(it1_c < it2_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it2_c < it3_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it1_c < it3_c, json::invalid_iterator&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(it1 < it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 < it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 < it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 < it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c < it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c < it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c < it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c < it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
#else
|
||||
CHECK_THROWS_WITH(it1 < it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 < it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 < it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
@ -533,6 +590,7 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_WITH(it1_c < it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c < it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -559,6 +617,16 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_AS(it1_c <= it2_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it2_c <= it3_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it1_c <= it3_c, json::invalid_iterator&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(it1 <= it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 <= it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 <= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 <= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c <= it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c <= it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c <= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c <= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
#else
|
||||
CHECK_THROWS_WITH(it1 <= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 <= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 <= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
@ -567,6 +635,7 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_WITH(it1_c <= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c <= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -594,6 +663,16 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_AS(it1_c > it2_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it2_c > it3_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it1_c > it3_c, json::invalid_iterator&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(it1 > it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 > it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 > it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 > it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c > it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c > it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c > it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c > it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
#else
|
||||
CHECK_THROWS_WITH(it1 > it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 > it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 > it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
@ -602,6 +681,7 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_WITH(it1_c > it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c > it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -629,6 +709,16 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_AS(it1_c >= it2_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it2_c >= it3_c, json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(it1_c >= it3_c, json::invalid_iterator&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(it1 >= it1, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 >= it2, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 >= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 >= it3, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c >= it1_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c >= it2_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c >= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c >= it3_c, "[json.exception.invalid_iterator.213] (/5) cannot compare order of object iterators");
|
||||
#else
|
||||
CHECK_THROWS_WITH(it1 >= it1, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1 >= it2, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2 >= it3, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
@ -637,6 +727,7 @@ TEST_CASE("iterators 2")
|
||||
CHECK_THROWS_WITH(it1_c >= it2_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it2_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
CHECK_THROWS_WITH(it1_c >= it3_c, "[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -662,13 +753,16 @@ TEST_CASE("iterators 2")
|
||||
{
|
||||
CHECK_THROWS_AS(j.rbegin() == k.rbegin(), json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(j.crbegin() == k.crbegin(), json::invalid_iterator&);
|
||||
CHECK_THROWS_WITH(j.rbegin() == k.rbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
CHECK_THROWS_WITH(j.crbegin() == k.crbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
|
||||
CHECK_THROWS_AS(j.rbegin() < k.rbegin(), json::invalid_iterator&);
|
||||
CHECK_THROWS_AS(j.crbegin() < k.crbegin(), json::invalid_iterator&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
// the output differs in each loop, so we cannot fix a string for the expected exception
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.rbegin() == k.rbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
CHECK_THROWS_WITH(j.crbegin() == k.crbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
CHECK_THROWS_WITH(j.rbegin() < k.rbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
CHECK_THROWS_WITH(j.crbegin() < k.crbegin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -343,7 +343,11 @@ TEST_CASE("JSON patch")
|
||||
|
||||
// check that evaluation throws
|
||||
CHECK_THROWS_AS(doc.patch(patch), json::other_error&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH_STD_STR(doc.patch(patch), "[json.exception.other_error.501] (/0) unsuccessful: " + patch[0].dump());
|
||||
#else
|
||||
CHECK_THROWS_WITH_STD_STR(doc.patch(patch), "[json.exception.other_error.501] unsuccessful: " + patch[0].dump());
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("A.10. Adding a Nested Member Object")
|
||||
@ -484,7 +488,11 @@ TEST_CASE("JSON patch")
|
||||
|
||||
// check that evaluation throws
|
||||
CHECK_THROWS_AS(doc.patch(patch), json::other_error&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH_STD_STR(doc.patch(patch), "[json.exception.other_error.501] (/0) unsuccessful: " + patch[0].dump());
|
||||
#else
|
||||
CHECK_THROWS_WITH_STD_STR(doc.patch(patch), "[json.exception.other_error.501] unsuccessful: " + patch[0].dump());
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("A.16. Adding an Array Value")
|
||||
@ -683,8 +691,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {"op", "add", "path", "", "value", 1};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.104] parse error: JSON patch must be an array of objects");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.104] parse error: (/0) JSON patch must be an array of objects");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.104] parse error: JSON patch must be an array of objects");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("missing 'op'")
|
||||
@ -692,8 +703,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"foo", "bar"}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation must have member 'op'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation must have member 'op'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation must have member 'op'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("non-string 'op'")
|
||||
@ -701,8 +715,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", 1}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation must have string member 'op'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation must have string member 'op'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation must have string member 'op'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("invalid operation")
|
||||
@ -710,8 +727,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "foo"}, {"path", ""}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation value 'foo' is invalid");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation value 'foo' is invalid");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation value 'foo' is invalid");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -722,8 +742,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "add"}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'add' must have member 'path'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'add' must have member 'path'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'add' must have member 'path'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("non-string 'path'")
|
||||
@ -731,8 +754,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "add"}, {"path", 1}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'add' must have string member 'path'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'add' must have string member 'path'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'add' must have string member 'path'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("missing 'value'")
|
||||
@ -740,8 +766,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "add"}, {"path", ""}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'add' must have member 'value'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'add' must have member 'value'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'add' must have member 'value'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("invalid array index")
|
||||
@ -761,8 +790,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "remove"}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'remove' must have member 'path'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'remove' must have member 'path'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'remove' must have member 'path'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("non-string 'path'")
|
||||
@ -770,8 +802,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "remove"}, {"path", 1}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'remove' must have string member 'path'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'remove' must have string member 'path'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'remove' must have string member 'path'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("nonexisting target location (array)")
|
||||
@ -809,8 +844,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "replace"}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'replace' must have member 'path'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'replace' must have member 'path'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'replace' must have member 'path'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("non-string 'path'")
|
||||
@ -818,8 +856,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "replace"}, {"path", 1}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'replace' must have string member 'path'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'replace' must have string member 'path'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'replace' must have string member 'path'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("missing 'value'")
|
||||
@ -827,8 +868,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "replace"}, {"path", ""}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'replace' must have member 'value'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'replace' must have member 'value'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'replace' must have member 'value'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("nonexisting target location (array)")
|
||||
@ -857,8 +901,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "move"}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'move' must have member 'path'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'move' must have member 'path'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'move' must have member 'path'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("non-string 'path'")
|
||||
@ -866,8 +913,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "move"}, {"path", 1}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'move' must have string member 'path'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'move' must have string member 'path'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'move' must have string member 'path'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("missing 'from'")
|
||||
@ -875,8 +925,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "move"}, {"path", ""}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'move' must have member 'from'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'move' must have member 'from'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'move' must have member 'from'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("non-string 'from'")
|
||||
@ -884,8 +937,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "move"}, {"path", ""}, {"from", 1}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'move' must have string member 'from'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'move' must have string member 'from'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'move' must have string member 'from'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("nonexisting from location (array)")
|
||||
@ -914,8 +970,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "copy"}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'copy' must have member 'path'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have member 'path'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'copy' must have member 'path'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("non-string 'path'")
|
||||
@ -923,8 +982,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "copy"}, {"path", 1}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'path'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have string member 'path'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'path'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("missing 'from'")
|
||||
@ -932,8 +994,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "copy"}, {"path", ""}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'copy' must have member 'from'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have member 'from'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'copy' must have member 'from'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("non-string 'from'")
|
||||
@ -941,8 +1006,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "copy"}, {"path", ""}, {"from", 1}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'copy' must have string member 'from'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("nonexisting from location (array)")
|
||||
@ -971,8 +1039,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "test"}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'test' must have member 'path'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'test' must have member 'path'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'test' must have member 'path'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("non-string 'path'")
|
||||
@ -980,8 +1051,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "test"}, {"path", 1}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'test' must have string member 'path'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'test' must have string member 'path'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'test' must have string member 'path'");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("missing 'value'")
|
||||
@ -989,8 +1063,11 @@ TEST_CASE("JSON patch")
|
||||
json j;
|
||||
json patch = {{{"op", "test"}, {"path", ""}}};
|
||||
CHECK_THROWS_AS(j.patch(patch), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.patch(patch),
|
||||
"[json.exception.parse_error.105] parse error: operation 'test' must have member 'value'");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: (/0) operation 'test' must have member 'value'");
|
||||
#else
|
||||
CHECK_THROWS_WITH(j.patch(patch), "[json.exception.parse_error.105] parse error: operation 'test' must have member 'value'");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1183,7 +1260,11 @@ TEST_CASE("JSON patch")
|
||||
|
||||
// the test will fail
|
||||
CHECK_THROWS_AS(doc.patch(patch), json::other_error&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH_STD_STR(doc.patch(patch), "[json.exception.other_error.501] (/0) unsuccessful: " + patch[0].dump());
|
||||
#else
|
||||
CHECK_THROWS_WITH_STD_STR(doc.patch(patch), "[json.exception.other_error.501] unsuccessful: " + patch[0].dump());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -496,8 +496,11 @@ TEST_CASE("JSON pointers")
|
||||
|
||||
// error for nonprimitve values
|
||||
CHECK_THROWS_AS(json({{"/1", {1, 2, 3}}}).unflatten(), json::type_error&);
|
||||
CHECK_THROWS_WITH(json({{"/1", {1, 2, 3}}}).unflatten(),
|
||||
"[json.exception.type_error.315] values in object must be primitive");
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(json({{"/1", {1, 2, 3}}}).unflatten(), "[json.exception.type_error.315] (/~11) values in object must be primitive");
|
||||
#else
|
||||
CHECK_THROWS_WITH(json({{"/1", {1, 2, 3}}}).unflatten(), "[json.exception.type_error.315] values in object must be primitive");
|
||||
#endif
|
||||
|
||||
// error for conflicting values
|
||||
json j_error = {{"", 42}, {"/foo", 17}};
|
||||
|
@ -394,7 +394,11 @@ TEST_CASE("regression tests 1")
|
||||
// improve coverage
|
||||
o["int"] = 1;
|
||||
CHECK_THROWS_AS(s2 = o["int"], json::type_error);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(s2 = o["int"], "[json.exception.type_error.302] (/int) type must be string, but is number");
|
||||
#else
|
||||
CHECK_THROWS_WITH(s2 = o["int"], "[json.exception.type_error.302] type must be string, but is number");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1181,8 +1181,8 @@ TEST_CASE("Unicode" * doctest::skip())
|
||||
CHECK_NOTHROW(json::json_pointer("/" + ptr));
|
||||
|
||||
// check escape/unescape roundtrip
|
||||
auto escaped = json::json_pointer::escape(ptr);
|
||||
json::json_pointer::unescape(escaped);
|
||||
auto escaped = nlohmann::detail::escape(ptr);
|
||||
nlohmann::detail::unescape(escaped);
|
||||
CHECK(escaped == ptr);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user