move diagnostic code in header

parent 43cd5c8a
......@@ -13,6 +13,7 @@
#include <valarray> // valarray
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/diagnostics_t.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
......@@ -27,7 +28,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, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
n = nullptr;
}
......@@ -58,7 +59,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
}
default:
JSON_THROW(type_error::create(302, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
}
......@@ -67,7 +68,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, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
}
......@@ -77,7 +78,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, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
}
......@@ -93,7 +94,7 @@ void from_json(const BasicJsonType& j, ConstructibleStringType& s)
{
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
{
JSON_THROW(type_error::create(302, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
......@@ -133,7 +134,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, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
l.clear();
std::transform(j.rbegin(), j.rend(),
......@@ -150,7 +151,7 @@ void from_json(const BasicJsonType& j, std::valarray<T>& l)
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
l.resize(j.size());
std::transform(j.begin(), j.end(), std::begin(l),
......@@ -241,8 +242,7 @@ void())
{
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
JSON_THROW(type_error::create(302, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
from_json_array_impl(j, arr, priority_tag<3> {});
......@@ -253,7 +253,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, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
......@@ -265,7 +265,7 @@ void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
{
if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
{
JSON_THROW(type_error::create(302, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
ConstructibleObjectType ret;
......@@ -319,7 +319,7 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
}
default:
JSON_THROW(type_error::create(302, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
}
......@@ -348,14 +348,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, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
m.clear();
for (const auto& p : j)
{
if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
{
JSON_THROW(type_error::create(302, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
}
......@@ -368,14 +368,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, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
m.clear();
for (const auto& p : j)
{
if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
{
JSON_THROW(type_error::create(302, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));
}
m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
}
......
#pragma once
#include <string>
#include <vector>
#include <nlohmann/detail/value_t.hpp>
namespace nlohmann
{
namespace detail
{
template<typename BasicJsonType>
class diagnostics_t
{
public:
diagnostics_t() noexcept = default;
diagnostics_t(const BasicJsonType& j) noexcept
: m_j(&j)
{}
std::string diagnostics() const
{
#if JSON_DIAGNOSTICS
if (m_j == nullptr)
{
return "";
}
std::vector<std::string> tokens;
for (const auto* current = m_j; 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 (current->m_parent->m_value.array->operator[](i) == *current)
{
tokens.emplace_back(std::to_string(i));
continue;
}
}
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());
continue;
}
}
break;
}
default:
break;
}
}
if (tokens.empty())
{
return "";
}
return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
[](const std::string & a, const std::string & b)
{
return a + "/" + b;
}) + ") ";
#else
return "";
#endif
}
private:
const BasicJsonType* m_j = static_cast<const BasicJsonType*>(nullptr);
};
} // namespace detail
} // namespace nlohmann
......@@ -4,6 +4,7 @@
#include <stdexcept> // runtime_error
#include <string> // to_string
#include <nlohmann/detail/diagnostics_t.hpp>
#include <nlohmann/detail/input/position_t.hpp>
#include <nlohmann/detail/macro_scope.hpp>
......@@ -127,18 +128,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 detail::diagnostics_t<BasicJsonType>& diagnostics)
{
std::string w = exception::name("parse_error", id_) + "parse error" +
position_string(pos) + ": " + what_arg;
position_string(pos) + ": " + diagnostics.diagnostics() + 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 detail::diagnostics_t<BasicJsonType>& diagnostics)
{
std::string w = exception::name("parse_error", id_) + "parse error" +
(byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
": " + what_arg;
": " + diagnostics.diagnostics() + what_arg;
return parse_error(id_, byte_, w.c_str());
}
......@@ -204,9 +207,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 detail::diagnostics_t<BasicJsonType>& diagnostics)
{
std::string w = exception::name("invalid_iterator", id_) + what_arg;
std::string w = exception::name("invalid_iterator", id_) + diagnostics.diagnostics() + what_arg;
return invalid_iterator(id_, w.c_str());
}
......@@ -258,9 +262,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 detail::diagnostics_t<BasicJsonType>& diagnostics)
{
std::string w = exception::name("type_error", id_) + what_arg;
std::string w = exception::name("type_error", id_) + diagnostics.diagnostics() + what_arg;
return type_error(id_, w.c_str());
}
......@@ -305,9 +310,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 detail::diagnostics_t<BasicJsonType>& diagnostics)
{
std::string w = exception::name("out_of_range", id_) + what_arg;
std::string w = exception::name("out_of_range", id_) + diagnostics.diagnostics() + what_arg;
return out_of_range(id_, w.c_str());
}
......@@ -343,9 +349,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 detail::diagnostics_t<BasicJsonType>& diagnostics)
{
std::string w = exception::name("other_error", id_) + what_arg;
std::string w = exception::name("other_error", id_) + diagnostics.diagnostics() + what_arg;
return other_error(id_, w.c_str());
}
......
......@@ -5,6 +5,7 @@
#include <utility> // move
#include <vector> // vector
#include <nlohmann/detail/diagnostics_t.hpp>
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp>
......@@ -154,6 +155,7 @@ class json_sax_dom_parser
using number_float_t = typename BasicJsonType::number_float_t;
using string_t = typename BasicJsonType::string_t;
using binary_t = typename BasicJsonType::binary_t;
using diagnostics_t = detail::diagnostics_t<BasicJsonType>;
/*!
@param[in, out] r reference to a JSON value that is manipulated while
......@@ -219,8 +221,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, ref_stack.back()->diagnostics() +
"excessive object size: " + std::to_string(len)));
JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), diagnostics_t(*ref_stack.back())));
}
return true;
......@@ -245,8 +246,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, ref_stack.back()->diagnostics() +
"excessive array size: " + std::to_string(len)));
JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), diagnostics_t(*ref_stack.back())));
}
return true;
......@@ -336,6 +336,7 @@ class json_sax_dom_callback_parser
using binary_t = typename BasicJsonType::binary_t;
using parser_callback_t = typename BasicJsonType::parser_callback_t;
using parse_event_t = typename BasicJsonType::parse_event_t;
using diagnostics_t = detail::diagnostics_t<BasicJsonType>;
json_sax_dom_callback_parser(BasicJsonType& r,
const parser_callback_t cb,
......@@ -406,7 +407,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, ref_stack.back()->diagnostics() + "excessive object size: " + std::to_string(len)));
JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), diagnostics_t(*ref_stack.back())));
}
return true;
......@@ -469,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, ref_stack.back()->diagnostics() + "excessive array size: " + std::to_string(len)));
JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), diagnostics_t(*ref_stack.back())));
}
return true;
......
......@@ -8,6 +8,7 @@
#include <vector> // vector
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/diagnostics_t.hpp>
#include <nlohmann/detail/input/input_adapters.hpp>
#include <nlohmann/detail/input/json_sax.hpp>
#include <nlohmann/detail/input/lexer.hpp>
......@@ -57,6 +58,7 @@ class parser
using string_t = typename BasicJsonType::string_t;
using lexer_t = lexer<BasicJsonType, InputAdapterType>;
using token_type = typename lexer_t::token_type;
using diagnostics_t = detail::diagnostics_t<BasicJsonType>;
public:
/// a parser reading from an input adapter
......@@ -96,7 +98,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"), diagnostics_t()));
}
// in case of an error, return discarded value
......@@ -125,7 +127,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"), diagnostics_t()));
}
// in case of an error, return discarded value
......@@ -162,7 +164,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")));
exception_message(token_type::end_of_input, "value"), diagnostics_t()));
}
return result;
......@@ -209,7 +211,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")));
exception_message(token_type::value_string, "object key"), diagnostics_t()));
}
if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
{
......@@ -222,7 +224,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")));
exception_message(token_type::name_separator, "object separator"), diagnostics_t()));
}
// remember we are now inside an object
......@@ -265,7 +267,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() + "'", diagnostics_t()));
}
if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
......@@ -336,7 +338,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::uninitialized, "value")));
exception_message(token_type::uninitialized, "value"), diagnostics_t()));
}
default: // the last token was unexpected
......@@ -344,7 +346,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::literal_or_value, "value")));
exception_message(token_type::literal_or_value, "value"), diagnostics_t()));
}
}
}
......@@ -391,7 +393,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")));
exception_message(token_type::end_array, "array"), diagnostics_t()));
}
else // object
{
......@@ -404,7 +406,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")));
exception_message(token_type::value_string, "object key"), diagnostics_t()));
}
if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
......@@ -418,7 +420,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")));
exception_message(token_type::name_separator, "object separator"), diagnostics_t()));
}
// parse values
......@@ -447,7 +449,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")));
exception_message(token_type::end_object, "object"), diagnostics_t()));
}
}
}
......
......@@ -3,6 +3,7 @@
#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
#include <type_traits> // conditional, is_const, remove_const
#include <nlohmann/detail/diagnostics_t.hpp>
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/iterators/internal_iterator.hpp>
#include <nlohmann/detail/iterators/primitive_iterator.hpp>
......@@ -51,6 +52,7 @@ class iter_impl
// make sure BasicJsonType is basic_json or const basic_json
static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
"iter_impl only accepts (const) basic_json");
using diagnostics_t = detail::diagnostics_t<BasicJsonType>;
public:
......@@ -257,7 +259,7 @@ class iter_impl
}
case value_t::null:
JSON_THROW(invalid_iterator::create(214, m_object->diagnostics() + "cannot get value"));
JSON_THROW(invalid_iterator::create(214, "cannot get value", diagnostics_t(*m_object)));
default:
{
......@@ -266,7 +268,7 @@ class iter_impl
return *m_object;
}
JSON_THROW(invalid_iterator::create(214, m_object->diagnostics() + "cannot get value"));
JSON_THROW(invalid_iterator::create(214, "cannot get value", diagnostics_t(*m_object)));
}
}
}
......@@ -300,7 +302,7 @@ class iter_impl
return m_object;
}
JSON_THROW(invalid_iterator::create(214, m_object->diagnostics() + "cannot get value"));
JSON_THROW(invalid_iterator::create(214, "cannot get value", diagnostics_t(*m_object)));
}
}
}
......@@ -401,7 +403,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, m_object->diagnostics() + "cannot compare iterators of different containers"));
JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", diagnostics_t(*m_object)));
}
JSON_ASSERT(m_object != nullptr);
......@@ -438,7 +440,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, m_object->diagnostics() + "cannot compare iterators of different containers"));
JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", diagnostics_t(*m_object)));
}
JSON_ASSERT(m_object != nullptr);
......@@ -446,7 +448,7 @@ class iter_impl
switch (m_object->m_type)
{
case value_t::object:
JSON_THROW(invalid_iterator::create(213, m_object->diagnostics() + "cannot compare order of object iterators"));
JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", diagnostics_t(*m_object)));
case value_t::array:
return (m_it.array_iterator < other.m_it.array_iterator);
......@@ -494,7 +496,7 @@ class iter_impl
switch (m_object->m_type)
{
case value_t::object:
JSON_THROW(invalid_iterator::create(209, m_object->diagnostics() + "cannot use offsets with object iterators"));
JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", diagnostics_t(*m_object)));
case value_t::array:
{
......@@ -565,7 +567,7 @@ class iter_impl
switch (m_object->m_type)
{
case value_t::object:
JSON_THROW(invalid_iterator::create(209, m_object->diagnostics() + "cannot use offsets with object iterators"));
JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", diagnostics_t(*m_object)));
case value_t::array:
return m_it.array_iterator - other.m_it.array_iterator;
......@@ -586,13 +588,13 @@ class iter_impl
switch (m_object->m_type)
{
case value_t::object:
JSON_THROW(invalid_iterator::create(208, m_object->diagnostics() + "cannot use operator[] for object iterators"));
JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", diagnostics_t(*m_object)));
case value_t::array:
return *std::next(m_it.array_iterator, n);
case value_t::null:
JSON_THROW(invalid_iterator::create(214, m_object->diagnostics() + "cannot get value"));
JSON_THROW(invalid_iterator::create(214, "cannot get value", diagnostics_t(*m_object)));
default:
{
......@@ -601,7 +603,7 @@ class iter_impl
return *m_object;
}
JSON_THROW(invalid_iterator::create(214, m_object->diagnostics() + "cannot get value"));
JSON_THROW(invalid_iterator::create(214, "cannot get value", diagnostics_t(*m_object)));
}
}
}
......@@ -619,7 +621,7 @@ class iter_impl
return m_it.object_iterator->first;
}
JSON_THROW(invalid_iterator::create(207, m_object->diagnostics() + "cannot use key() for non-object iterators"));
JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", diagnostics_t(*m_object)));
}
/*!
......
......@@ -8,6 +8,7 @@
#include <utility> // move
#include <vector> // vector
#include <nlohmann/detail/diagnostics_t.hpp>
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/value_t.hpp>
......@@ -21,6 +22,8 @@ class json_pointer
NLOHMANN_BASIC_JSON_TPL_DECLARATION
friend class basic_json;
using diagnostics_t = detail::diagnostics_t<BasicJsonType>;
public:
/*!
@brief create JSON pointer
......@@ -247,7 +250,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", diagnostics_t()));
}
reference_tokens.pop_back();
......@@ -271,7 +274,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", diagnostics_t()));
}
return reference_tokens.back();
......@@ -337,15 +340,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'", diagnostics_t()));
}
// 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", diagnostics_t()));
}
std::size_t processed_chars = 0;
......@@ -356,20 +357,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 + "'", diagnostics_t()));
}
// 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 + "'", diagnostics_t()));
}
// 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", diagnostics_t())); // LCOV_EXCL_LINE
}
return static_cast<size_type>(res);
......@@ -380,7 +381,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", diagnostics_t()));
}
json_pointer result = *this;
......@@ -443,7 +444,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", diagnostics_t(j)));
}
}
......@@ -515,7 +516,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 + "'", diagnostics_t(*ptr)));
}
}
......@@ -548,7 +549,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", diagnostics_t(*ptr)));
}
// note: at performs range check
......@@ -557,7 +558,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 + "'", diagnostics_t(*ptr)));
}
}
......@@ -595,9 +596,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", diagnostics_t(*ptr)));
}
// use unchecked array access
......@@ -606,7 +605,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 + "'", diagnostics_t(*ptr)));
}
}
......@@ -639,7 +638,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", diagnostics_t(*ptr)));
}
// note: at performs range check
......@@ -648,7 +647,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 + "'", diagnostics_t(*ptr)));
}
}
......@@ -752,9 +751,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 + "'", diagnostics_t()));
}
// extract the reference tokens:
......@@ -789,7 +786,7 @@ 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'", diagnostics_t()));
}
}
......@@ -916,7 +913,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", diagnostics_t(value)));
}
BasicJsonType result;
......@@ -926,7 +923,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", diagnostics_t(element)));
}
// assign value to reference pointed to by JSON pointer; Note that if
......
......@@ -8,6 +8,7 @@
#include <string> // string
#include <cmath> // isnan, isinf
#include <nlohmann/detail/diagnostics_t.hpp>
#include <nlohmann/detail/input/binary_reader.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/output/output_adapters.hpp>
......@@ -57,7 +58,7 @@ class binary_writer
default:
{
JSON_THROW(type_error::create(317, j.diagnostics() + "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()), detail::diagnostics_t<BasicJsonType>(j)));;
}
}
}
......@@ -906,8 +907,7 @@ class binary_writer
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, j.diagnostics() +
"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) + ")", detail::diagnostics_t<BasicJsonType>(j)));
}
return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
......@@ -1031,7 +1031,7 @@ class binary_writer
}
else
{
JSON_THROW(out_of_range::create(407, j.diagnostics() + "integer number " + std::to_string(j.m_value.number_unsigned) + " 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", detail::diagnostics_t<BasicJsonType>(j)));
}
}
......
......@@ -13,6 +13,7 @@
#include <utility> // move
#include <nlohmann/detail/conversions/to_chars.hpp>
#include <nlohmann/detail/diagnostics_t.hpp>
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
......@@ -499,7 +500,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, detail::diagnostics_t<BasicJsonType>()));
}
case error_handler_t::ignore:
......@@ -593,7 +594,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, detail::diagnostics_t<BasicJsonType>()));
}
case error_handler_t::ignore:
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment