mirror of
https://github.com/nlohmann/json.git
synced 2026-10-24 06:48:55 +00:00
2.4.1/1.7: exceptions: share what_impl, flatten diagnostics switch (#5891)
The four create() bodies build their message through one protected static helper; the diagnostics parent walk handles array/object and ignores all other types. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
1 file changed
+32
-40
@@ -150,6 +150,13 @@ class exception : public std::exception
|
||||
return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
|
||||
}
|
||||
|
||||
/// build the message "[json.exception.<ename>.<id>] <diagnostics><what_arg>"
|
||||
template<typename BasicJsonContext>
|
||||
static std::string what_impl(const std::string& ename, int id_, const std::string& what_arg, BasicJsonContext context)
|
||||
{
|
||||
return concat(name(ename, id_), diagnostics(context), what_arg);
|
||||
}
|
||||
|
||||
static std::string diagnostics(std::nullptr_t /*leaf_element*/)
|
||||
{
|
||||
return "";
|
||||
@@ -162,48 +169,33 @@ class exception : public std::exception
|
||||
std::vector<std::string> tokens;
|
||||
for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
|
||||
{
|
||||
switch (current->m_parent->type())
|
||||
const auto* parent = current->m_parent;
|
||||
if (parent->is_array())
|
||||
{
|
||||
case value_t::array:
|
||||
for (std::size_t i = 0; i < parent->m_data.m_value.array->size(); ++i)
|
||||
{
|
||||
for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i)
|
||||
if (&parent->m_data.m_value.array->operator[](i) == current)
|
||||
{
|
||||
if (¤t->m_parent->m_data.m_value.array->operator[](i) == current)
|
||||
{
|
||||
tokens.emplace_back(std::to_string(i));
|
||||
break;
|
||||
}
|
||||
tokens.emplace_back(std::to_string(i));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::object:
|
||||
{
|
||||
for (const auto& element : *current->m_parent->m_data.m_value.object)
|
||||
{
|
||||
if (&element.second == current)
|
||||
{
|
||||
// data() is null-terminated, so a key containing
|
||||
// a null byte is cut short here rather than
|
||||
// truncating the whole message at what()
|
||||
tokens.emplace_back(element.first.data());
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::null: // LCOV_EXCL_LINE
|
||||
case value_t::string: // LCOV_EXCL_LINE
|
||||
case value_t::boolean: // LCOV_EXCL_LINE
|
||||
case value_t::number_integer: // LCOV_EXCL_LINE
|
||||
case value_t::number_unsigned: // LCOV_EXCL_LINE
|
||||
case value_t::number_float: // LCOV_EXCL_LINE
|
||||
case value_t::binary: // LCOV_EXCL_LINE
|
||||
case value_t::discarded: // LCOV_EXCL_LINE
|
||||
default: // LCOV_EXCL_LINE
|
||||
break; // LCOV_EXCL_LINE
|
||||
}
|
||||
else if (parent->is_object())
|
||||
{
|
||||
for (const auto& element : *parent->m_data.m_value.object)
|
||||
{
|
||||
if (&element.second == current)
|
||||
{
|
||||
// data() is null-terminated, so a key containing
|
||||
// a null byte is cut short here rather than
|
||||
// truncating the whole message at what()
|
||||
tokens.emplace_back(element.first.data());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// all other parent types (primitives) contribute no token
|
||||
}
|
||||
|
||||
if (tokens.empty())
|
||||
@@ -319,7 +311,7 @@ class invalid_iterator : public exception
|
||||
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
|
||||
static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
|
||||
{
|
||||
const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
|
||||
const std::string w = exception::what_impl("invalid_iterator", id_, what_arg, context);
|
||||
return {id_, w.c_str()};
|
||||
}
|
||||
|
||||
@@ -343,7 +335,7 @@ class type_error : public exception
|
||||
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
|
||||
static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
|
||||
{
|
||||
const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
|
||||
const std::string w = exception::what_impl("type_error", id_, what_arg, context);
|
||||
return {id_, w.c_str()};
|
||||
}
|
||||
|
||||
@@ -366,7 +358,7 @@ class out_of_range : public exception
|
||||
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
|
||||
static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
|
||||
{
|
||||
const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
|
||||
const std::string w = exception::what_impl("out_of_range", id_, what_arg, context);
|
||||
return {id_, w.c_str()};
|
||||
}
|
||||
|
||||
@@ -389,7 +381,7 @@ class other_error : public exception
|
||||
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
|
||||
static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
|
||||
{
|
||||
const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
|
||||
const std::string w = exception::what_impl("other_error", id_, what_arg, context);
|
||||
return {id_, w.c_str()};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user