🚑 made exceptions nothrow-copy-constructible #531

To have nothrow-copy-constructible exceptions, we inherit from std::runtime_error which can cope with arbitrary-length error messages. Intermediate strings are built with static functions and then passed to the actual constructor.
parent a58ed3cd
...@@ -894,7 +894,7 @@ $ make json_unit -Ctest ...@@ -894,7 +894,7 @@ $ make json_unit -Ctest
$ ./test/json_unit "*" $ ./test/json_unit "*"
=============================================================================== ===============================================================================
All tests passed (11202597 assertions in 47 test cases) All tests passed (11203022 assertions in 48 test cases)
``` ```
Alternatively, you can use [CMake](https://cmake.org) and run Alternatively, you can use [CMake](https://cmake.org) and run
......
...@@ -116,29 +116,34 @@ namespace detail ...@@ -116,29 +116,34 @@ namespace detail
Extension of std::exception objects with a member @a id for exception ids. Extension of std::exception objects with a member @a id for exception ids.
@note To have nothrow-copy-constructible exceptions, we inherit from
std::runtime_error which can cope with arbitrary-length error messages.
Intermediate strings are built with static functions and then passed to
the actual constructor.
@since version 3.0.0 @since version 3.0.0
*/ */
class exception : public std::exception class exception : public std::runtime_error
{ {
public: public:
/// create exception with id an explanatory string
exception(int id_, const std::string& ename, const std::string& what_arg_)
: id(id_),
what_arg("[json.exception." + ename + "." + std::to_string(id_) + "] " + what_arg_)
{}
/// returns the explanatory string /// returns the explanatory string
virtual const char* what() const noexcept override virtual const char* what() const noexcept override
{ {
return what_arg.c_str(); return std::runtime_error::what();
} }
/// the id of the exception /// the id of the exception
const int id; const int id;
private: protected:
/// the explanatory string exception(int id_, const char* what_arg)
const std::string what_arg; : std::runtime_error(what_arg), id(id_)
{}
static std::string name(const std::string& ename, int id_)
{
return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
}
}; };
/*! /*!
...@@ -184,14 +189,16 @@ class parse_error : public exception ...@@ -184,14 +189,16 @@ class parse_error : public exception
@param[in] id_ the id of the exception @param[in] id_ the id of the exception
@param[in] byte_ the byte index where the error occured (or 0 if @param[in] byte_ the byte index where the error occured (or 0 if
the position cannot be determined) the position cannot be determined)
@param[in] what_arg_ the explanatory string @param[in] what_arg the explanatory string
@return parse_error object
*/ */
parse_error(int id_, size_t byte_, const std::string& what_arg_) static parse_error create(int id_, size_t byte_, const std::string& what_arg)
: exception(id_, "parse_error", "parse error" + {
std::string w = exception::name("parse_error", id_) + "parse error" +
(byte_ != 0 ? (" at " + std::to_string(byte_)) : "") + (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
": " + what_arg_), ": " + what_arg;
byte(byte_) return parse_error(id_, byte_, w.c_str());
{} }
/*! /*!
@brief byte index of the parse error @brief byte index of the parse error
...@@ -204,6 +211,12 @@ class parse_error : public exception ...@@ -204,6 +211,12 @@ class parse_error : public exception
MessagePack). MessagePack).
*/ */
const size_t byte; const size_t byte;
private:
parse_error(int id_, size_t byte_, const char* what_arg)
: exception(id_, what_arg),
byte(byte_)
{}
}; };
/*! /*!
...@@ -233,8 +246,15 @@ json.exception.invalid_iterator.214 | cannot get value | Cannot get value for it ...@@ -233,8 +246,15 @@ json.exception.invalid_iterator.214 | cannot get value | Cannot get value for it
class invalid_iterator : public exception class invalid_iterator : public exception
{ {
public: public:
invalid_iterator(int id_, const std::string& what_arg_) static invalid_iterator create(int id_, const std::string& what_arg)
: exception(id_, "invalid_iterator", what_arg_) {
std::string w = exception::name("invalid_iterator", id_) + what_arg;
return invalid_iterator(id_, w.c_str());
}
private:
invalid_iterator(int id_, const char* what_arg)
: exception(id_, what_arg)
{} {}
}; };
...@@ -265,8 +285,15 @@ json.exception.type_error.315 | values in object must be primitive | The @ref un ...@@ -265,8 +285,15 @@ json.exception.type_error.315 | values in object must be primitive | The @ref un
class type_error : public exception class type_error : public exception
{ {
public: public:
type_error(int id_, const std::string& what_arg_) static type_error create(int id_, const std::string& what_arg)
: exception(id_, "type_error", what_arg_) {
std::string w = exception::name("type_error", id_) + what_arg;
return type_error(id_, w.c_str());
}
private:
type_error(int id_, const char* what_arg)
: exception(id_, what_arg)
{} {}
}; };
...@@ -289,8 +316,15 @@ json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed n ...@@ -289,8 +316,15 @@ json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed n
class out_of_range : public exception class out_of_range : public exception
{ {
public: public:
out_of_range(int id_, const std::string& what_arg_) static out_of_range create(int id_, const std::string& what_arg)
: exception(id_, "out_of_range", what_arg_) {
std::string w = exception::name("out_of_range", id_) + what_arg;
return out_of_range(id_, w.c_str());
}
private:
out_of_range(int id_, const char* what_arg)
: exception(id_, what_arg)
{} {}
}; };
...@@ -308,8 +342,15 @@ json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "valu ...@@ -308,8 +342,15 @@ json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "valu
class other_error : public exception class other_error : public exception
{ {
public: public:
other_error(int id_, const std::string& what_arg_) static other_error create(int id_, const std::string& what_arg)
: exception(id_, "other_error", what_arg_) {
std::string w = exception::name("other_error", id_) + what_arg;
return other_error(id_, w.c_str());
}
private:
other_error(int id_, const char* what_arg)
: exception(id_, what_arg)
{} {}
}; };
...@@ -841,7 +882,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) ...@@ -841,7 +882,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
} }
default: default:
{ {
JSON_THROW(type_error(302, "type must be number, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be number, but is " + j.type_name()));
} }
} }
} }
...@@ -851,7 +892,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) ...@@ -851,7 +892,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
{ {
if (not j.is_boolean()) if (not j.is_boolean())
{ {
JSON_THROW(type_error(302, "type must be boolean, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be boolean, but is " + j.type_name()));
} }
b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>(); b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
} }
...@@ -861,7 +902,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) ...@@ -861,7 +902,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
{ {
if (not j.is_string()) if (not j.is_string())
{ {
JSON_THROW(type_error(302, "type must be string, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be string, but is " + j.type_name()));
} }
s = *j.template get_ptr<const typename BasicJsonType::string_t*>(); s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
} }
...@@ -898,7 +939,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr) ...@@ -898,7 +939,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
{ {
if (not j.is_array()) if (not j.is_array())
{ {
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be array, but is " + j.type_name()));
} }
arr = *j.template get_ptr<const typename BasicJsonType::array_t*>(); arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
} }
...@@ -910,7 +951,7 @@ void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l) ...@@ -910,7 +951,7 @@ void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
{ {
if (not j.is_array()) if (not j.is_array())
{ {
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be array, but is " + j.type_name()));
} }
for (auto it = j.rbegin(), end = j.rend(); it != end; ++it) for (auto it = j.rbegin(), end = j.rend(); it != end; ++it)
...@@ -961,7 +1002,7 @@ void from_json(const BasicJsonType& j, CompatibleArrayType& arr) ...@@ -961,7 +1002,7 @@ void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
{ {
if (not j.is_array()) if (not j.is_array())
{ {
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be array, but is " + j.type_name()));
} }
from_json_array_impl(j, arr, priority_tag<1> {}); from_json_array_impl(j, arr, priority_tag<1> {});
...@@ -973,7 +1014,7 @@ void from_json(const BasicJsonType& j, CompatibleObjectType& obj) ...@@ -973,7 +1014,7 @@ void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
{ {
if (not j.is_object()) if (not j.is_object())
{ {
JSON_THROW(type_error(302, "type must be object, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be object, but is " + j.type_name()));
} }
auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>(); auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
...@@ -1023,7 +1064,7 @@ void from_json(const BasicJsonType& j, ArithmeticType& val) ...@@ -1023,7 +1064,7 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
} }
default: default:
{ {
JSON_THROW(type_error(302, "type must be number, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be number, but is " + j.type_name()));
} }
} }
} }
...@@ -1970,7 +2011,7 @@ class basic_json ...@@ -1970,7 +2011,7 @@ class basic_json
{ {
if (t == value_t::null) if (t == value_t::null)
{ {
JSON_THROW(other_error(500, "961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE
} }
break; break;
} }
...@@ -2325,7 +2366,7 @@ class basic_json ...@@ -2325,7 +2366,7 @@ class basic_json
// if object is wanted but impossible, throw an exception // if object is wanted but impossible, throw an exception
if (manual_type == value_t::object and not is_an_object) if (manual_type == value_t::object and not is_an_object)
{ {
JSON_THROW(type_error(301, "cannot create object from initializer list")); JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
} }
} }
...@@ -2509,7 +2550,7 @@ class basic_json ...@@ -2509,7 +2550,7 @@ class basic_json
// make sure iterator fits the current value // make sure iterator fits the current value
if (first.m_object != last.m_object) if (first.m_object != last.m_object)
{ {
JSON_THROW(invalid_iterator(201, "iterators are not compatible")); JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
} }
// copy type from first iterator // copy type from first iterator
...@@ -2526,7 +2567,7 @@ class basic_json ...@@ -2526,7 +2567,7 @@ class basic_json
{ {
if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end()) if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
{ {
JSON_THROW(invalid_iterator(204, "iterators out of range")); JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
} }
break; break;
} }
...@@ -2585,7 +2626,7 @@ class basic_json ...@@ -2585,7 +2626,7 @@ class basic_json
default: default:
{ {
JSON_THROW(invalid_iterator(206, "cannot construct with iterators from " + JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
first.m_object->type_name())); first.m_object->type_name()));
} }
} }
...@@ -3224,7 +3265,7 @@ class basic_json ...@@ -3224,7 +3265,7 @@ class basic_json
return m_value.boolean; return m_value.boolean;
} }
JSON_THROW(type_error(302, "type must be boolean, but is " + type_name())); JSON_THROW(type_error::create(302, "type must be boolean, but is " + type_name()));
} }
/// get a pointer to the value (object) /// get a pointer to the value (object)
...@@ -3336,7 +3377,7 @@ class basic_json ...@@ -3336,7 +3377,7 @@ class basic_json
return *ptr; return *ptr;
} }
JSON_THROW(type_error(303, "incompatible ReferenceType for get_ref, actual type is " + obj.type_name())); JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + obj.type_name()));
} }
public: public:
...@@ -3738,12 +3779,12 @@ class basic_json ...@@ -3738,12 +3779,12 @@ class basic_json
JSON_CATCH (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
JSON_THROW(out_of_range(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"));
} }
} }
else else
{ {
JSON_THROW(type_error(304, "cannot use at() with " + type_name())); JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
} }
} }
...@@ -3785,12 +3826,12 @@ class basic_json ...@@ -3785,12 +3826,12 @@ class basic_json
JSON_CATCH (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
JSON_THROW(out_of_range(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"));
} }
} }
else else
{ {
JSON_THROW(type_error(304, "cannot use at() with " + type_name())); JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
} }
} }
...@@ -3836,12 +3877,12 @@ class basic_json ...@@ -3836,12 +3877,12 @@ class basic_json
JSON_CATCH (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
JSON_THROW(out_of_range(403, "key '" + key + "' not found")); JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
} }
} }
else else
{ {
JSON_THROW(type_error(304, "cannot use at() with " + type_name())); JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
} }
} }
...@@ -3887,12 +3928,12 @@ class basic_json ...@@ -3887,12 +3928,12 @@ class basic_json
JSON_CATCH (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
JSON_THROW(out_of_range(403, "key '" + key + "' not found")); JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
} }
} }
else else
{ {
JSON_THROW(type_error(304, "cannot use at() with " + type_name())); JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
} }
} }
...@@ -3945,7 +3986,7 @@ class basic_json ...@@ -3945,7 +3986,7 @@ class basic_json
return m_value.array->operator[](idx); return m_value.array->operator[](idx);
} }
JSON_THROW(type_error(305, "cannot use operator[] with " + type_name())); JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
} }
/*! /*!
...@@ -3975,7 +4016,7 @@ class basic_json ...@@ -3975,7 +4016,7 @@ class basic_json
return m_value.array->operator[](idx); return m_value.array->operator[](idx);
} }
JSON_THROW(type_error(305, "cannot use operator[] with " + type_name())); JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
} }
/*! /*!
...@@ -4021,7 +4062,7 @@ class basic_json ...@@ -4021,7 +4062,7 @@ class basic_json
return m_value.object->operator[](key); return m_value.object->operator[](key);
} }
JSON_THROW(type_error(305, "cannot use operator[] with " + type_name())); JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
} }
/*! /*!
...@@ -4063,7 +4104,7 @@ class basic_json ...@@ -4063,7 +4104,7 @@ class basic_json
return m_value.object->find(key)->second; return m_value.object->find(key)->second;
} }
JSON_THROW(type_error(305, "cannot use operator[] with " + type_name())); JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
} }
/*! /*!
...@@ -4178,7 +4219,7 @@ class basic_json ...@@ -4178,7 +4219,7 @@ class basic_json
return m_value.object->operator[](key); return m_value.object->operator[](key);
} }
JSON_THROW(type_error(305, "cannot use operator[] with " + type_name())); JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
} }
/*! /*!
...@@ -4221,7 +4262,7 @@ class basic_json ...@@ -4221,7 +4262,7 @@ class basic_json
return m_value.object->find(key)->second; return m_value.object->find(key)->second;
} }
JSON_THROW(type_error(305, "cannot use operator[] with " + type_name())); JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
} }
/*! /*!
...@@ -4290,7 +4331,7 @@ class basic_json ...@@ -4290,7 +4331,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(type_error(306, "cannot use value() with " + type_name())); JSON_THROW(type_error::create(306, "cannot use value() with " + type_name()));
} }
} }
...@@ -4362,7 +4403,7 @@ class basic_json ...@@ -4362,7 +4403,7 @@ class basic_json
} }
} }
JSON_THROW(type_error(306, "cannot use value() with " + type_name())); JSON_THROW(type_error::create(306, "cannot use value() with " + type_name()));
} }
/*! /*!
...@@ -4515,7 +4556,7 @@ class basic_json ...@@ -4515,7 +4556,7 @@ class basic_json
// make sure iterator fits the current value // make sure iterator fits the current value
if (this != pos.m_object) if (this != pos.m_object)
{ {
JSON_THROW(invalid_iterator(202, "iterator does not fit current value")); JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
} }
IteratorType result = end(); IteratorType result = end();
...@@ -4530,7 +4571,7 @@ class basic_json ...@@ -4530,7 +4571,7 @@ class basic_json
{ {
if (not pos.m_it.primitive_iterator.is_begin()) if (not pos.m_it.primitive_iterator.is_begin())
{ {
JSON_THROW(invalid_iterator(205, "iterator out of range")); JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
} }
if (is_string()) if (is_string())
...@@ -4560,7 +4601,7 @@ class basic_json ...@@ -4560,7 +4601,7 @@ class basic_json
default: default:
{ {
JSON_THROW(type_error(307, "cannot use erase() with " + type_name())); JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
} }
} }
...@@ -4622,7 +4663,7 @@ class basic_json ...@@ -4622,7 +4663,7 @@ class basic_json
// make sure iterator fits the current value // make sure iterator fits the current value
if (this != first.m_object or this != last.m_object) if (this != first.m_object or this != last.m_object)
{ {
JSON_THROW(invalid_iterator(203, "iterators do not fit current value")); JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
} }
IteratorType result = end(); IteratorType result = end();
...@@ -4637,7 +4678,7 @@ class basic_json ...@@ -4637,7 +4678,7 @@ class basic_json
{ {
if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end()) if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
{ {
JSON_THROW(invalid_iterator(204, "iterators out of range")); JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
} }
if (is_string()) if (is_string())
...@@ -4669,7 +4710,7 @@ class basic_json ...@@ -4669,7 +4710,7 @@ class basic_json
default: default:
{ {
JSON_THROW(type_error(307, "cannot use erase() with " + type_name())); JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
} }
} }
...@@ -4713,7 +4754,7 @@ class basic_json ...@@ -4713,7 +4754,7 @@ class basic_json
return m_value.object->erase(key); return m_value.object->erase(key);
} }
JSON_THROW(type_error(307, "cannot use erase() with " + type_name())); JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
} }
/*! /*!
...@@ -4747,14 +4788,14 @@ class basic_json ...@@ -4747,14 +4788,14 @@ class basic_json
{ {
if (idx >= size()) if (idx >= size())
{ {
JSON_THROW(out_of_range(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"));
} }
m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx)); m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
} }
else else
{ {
JSON_THROW(type_error(307, "cannot use erase() with " + type_name())); JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
} }
} }
...@@ -5472,7 +5513,7 @@ class basic_json ...@@ -5472,7 +5513,7 @@ class basic_json
// push_back only works for null objects or arrays // push_back only works for null objects or arrays
if (not(is_null() or is_array())) if (not(is_null() or is_array()))
{ {
JSON_THROW(type_error(308, "cannot use push_back() with " + type_name())); JSON_THROW(type_error::create(308, "cannot use push_back() with " + type_name()));
} }
// transform null object into an array // transform null object into an array
...@@ -5508,7 +5549,7 @@ class basic_json ...@@ -5508,7 +5549,7 @@ class basic_json
// push_back only works for null objects or arrays // push_back only works for null objects or arrays
if (not(is_null() or is_array())) if (not(is_null() or is_array()))
{ {
JSON_THROW(type_error(308, "cannot use push_back() with " + type_name())); JSON_THROW(type_error::create(308, "cannot use push_back() with " + type_name()));
} }
// transform null object into an array // transform null object into an array
...@@ -5558,7 +5599,7 @@ class basic_json ...@@ -5558,7 +5599,7 @@ class basic_json
// push_back only works for null objects or objects // push_back only works for null objects or objects
if (not(is_null() or is_object())) if (not(is_null() or is_object()))
{ {
JSON_THROW(type_error(308, "cannot use push_back() with " + type_name())); JSON_THROW(type_error::create(308, "cannot use push_back() with " + type_name()));
} }
// transform null object into an object // transform null object into an object
...@@ -5658,7 +5699,7 @@ class basic_json ...@@ -5658,7 +5699,7 @@ class basic_json
// emplace_back only works for null objects or arrays // emplace_back only works for null objects or arrays
if (not(is_null() or is_array())) if (not(is_null() or is_array()))
{ {
JSON_THROW(type_error(311, "cannot use emplace_back() with " + type_name())); JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + type_name()));
} }
// transform null object into an array // transform null object into an array
...@@ -5706,7 +5747,7 @@ class basic_json ...@@ -5706,7 +5747,7 @@ class basic_json
// emplace only works for null objects or arrays // emplace only works for null objects or arrays
if (not(is_null() or is_object())) if (not(is_null() or is_object()))
{ {
JSON_THROW(type_error(311, "cannot use emplace() with " + type_name())); JSON_THROW(type_error::create(311, "cannot use emplace() with " + type_name()));
} }
// transform null object into an object // transform null object into an object
...@@ -5757,7 +5798,7 @@ class basic_json ...@@ -5757,7 +5798,7 @@ class basic_json
// check if iterator pos fits to this JSON value // check if iterator pos fits to this JSON value
if (pos.m_object != this) if (pos.m_object != this)
{ {
JSON_THROW(invalid_iterator(202, "iterator does not fit current value")); JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
} }
// insert to array and return iterator // insert to array and return iterator
...@@ -5766,7 +5807,7 @@ class basic_json ...@@ -5766,7 +5807,7 @@ class basic_json
return result; return result;
} }
JSON_THROW(type_error(309, "cannot use insert() with " + type_name())); JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
} }
/*! /*!
...@@ -5810,7 +5851,7 @@ class basic_json ...@@ -5810,7 +5851,7 @@ class basic_json
// check if iterator pos fits to this JSON value // check if iterator pos fits to this JSON value
if (pos.m_object != this) if (pos.m_object != this)
{ {
JSON_THROW(invalid_iterator(202, "iterator does not fit current value")); JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
} }
// insert to array and return iterator // insert to array and return iterator
...@@ -5819,7 +5860,7 @@ class basic_json ...@@ -5819,7 +5860,7 @@ class basic_json
return result; return result;
} }
JSON_THROW(type_error(309, "cannot use insert() with " + type_name())); JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
} }
/*! /*!
...@@ -5857,24 +5898,24 @@ class basic_json ...@@ -5857,24 +5898,24 @@ class basic_json
// insert only works for arrays // insert only works for arrays
if (not is_array()) if (not is_array())
{ {
JSON_THROW(type_error(309, "cannot use insert() with " + type_name())); JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
} }
// check if iterator pos fits to this JSON value // check if iterator pos fits to this JSON value
if (pos.m_object != this) if (pos.m_object != this)
{ {
JSON_THROW(invalid_iterator(202, "iterator does not fit current value")); JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
} }
// check if range iterators belong to the same JSON object // check if range iterators belong to the same JSON object
if (first.m_object != last.m_object) if (first.m_object != last.m_object)
{ {
JSON_THROW(invalid_iterator(210, "iterators do not fit")); JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
} }
if (first.m_object == this or last.m_object == this) if (first.m_object == this or last.m_object == this)
{ {
JSON_THROW(invalid_iterator(211, "passed iterators may not belong to container")); JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
} }
// insert to array and return iterator // insert to array and return iterator
...@@ -5915,13 +5956,13 @@ class basic_json ...@@ -5915,13 +5956,13 @@ class basic_json
// insert only works for arrays // insert only works for arrays
if (not is_array()) if (not is_array())
{ {
JSON_THROW(type_error(309, "cannot use insert() with " + type_name())); JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
} }
// check if iterator pos fits to this JSON value // check if iterator pos fits to this JSON value
if (pos.m_object != this) if (pos.m_object != this)
{ {
JSON_THROW(invalid_iterator(202, "iterator does not fit current value")); JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
} }
// insert to array and return iterator // insert to array and return iterator
...@@ -5988,7 +6029,7 @@ class basic_json ...@@ -5988,7 +6029,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(type_error(310, "cannot use swap() with " + type_name())); JSON_THROW(type_error::create(310, "cannot use swap() with " + type_name()));
} }
} }
...@@ -6021,7 +6062,7 @@ class basic_json ...@@ -6021,7 +6062,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(type_error(310, "cannot use swap() with " + type_name())); JSON_THROW(type_error::create(310, "cannot use swap() with " + type_name()));
} }
} }
...@@ -6054,7 +6095,7 @@ class basic_json ...@@ -6054,7 +6095,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(type_error(310, "cannot use swap() with " + type_name())); JSON_THROW(type_error::create(310, "cannot use swap() with " + type_name()));
} }
} }
...@@ -7999,19 +8040,19 @@ class basic_json ...@@ -7999,19 +8040,19 @@ class basic_json
// simple case: requested length is greater than the vector's length // simple case: requested length is greater than the vector's length
if (len > size or offset > size) if (len > size or offset > size)
{ {
JSON_THROW(parse_error(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector")); JSON_THROW(parse_error::create(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector"));
} }
// second case: adding offset would result in overflow // second case: adding offset would result in overflow
if ((size > ((std::numeric_limits<size_t>::max)() - offset))) if ((size > ((std::numeric_limits<size_t>::max)() - offset)))
{ {
JSON_THROW(parse_error(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector")); JSON_THROW(parse_error::create(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector"));
} }
// last case: reading past the end of the vector // last case: reading past the end of the vector
if (len + offset > size) if (len + offset > size)
{ {
JSON_THROW(parse_error(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector")); JSON_THROW(parse_error::create(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector"));
} }
} }
...@@ -8043,7 +8084,7 @@ class basic_json ...@@ -8043,7 +8084,7 @@ class basic_json
std::stringstream ss; std::stringstream ss;
ss << std::hex << static_cast<int>(v[idx]); ss << std::hex << static_cast<int>(v[idx]);
JSON_THROW(parse_error(113, idx + 1, "expected a MessagePack string; last byte: 0x" + ss.str())); JSON_THROW(parse_error::create(113, idx + 1, "expected a MessagePack string; last byte: 0x" + ss.str()));
} }
/*! /*!
...@@ -8073,7 +8114,7 @@ class basic_json ...@@ -8073,7 +8114,7 @@ class basic_json
std::stringstream ss; std::stringstream ss;
ss << std::hex << static_cast<int>(v[idx]); ss << std::hex << static_cast<int>(v[idx]);
JSON_THROW(parse_error(113, idx + 1, "expected a CBOR string; last byte: 0x" + ss.str())); JSON_THROW(parse_error::create(113, idx + 1, "expected a CBOR string; last byte: 0x" + ss.str()));
} }
/*! /*!
...@@ -8316,7 +8357,7 @@ class basic_json ...@@ -8316,7 +8357,7 @@ class basic_json
{ {
std::stringstream ss; std::stringstream ss;
ss << std::hex << static_cast<int>(v[current_idx]); ss << std::hex << static_cast<int>(v[current_idx]);
JSON_THROW(parse_error(112, current_idx + 1, "error reading MessagePack; last byte: 0x" + ss.str())); JSON_THROW(parse_error::create(112, current_idx + 1, "error reading MessagePack; last byte: 0x" + ss.str()));
} }
} }
} }
...@@ -8816,7 +8857,7 @@ class basic_json ...@@ -8816,7 +8857,7 @@ class basic_json
{ {
std::stringstream ss; std::stringstream ss;
ss << std::hex << static_cast<int>(v[current_idx]); ss << std::hex << static_cast<int>(v[current_idx]);
JSON_THROW(parse_error(112, current_idx + 1, "error reading CBOR; last byte: 0x" + ss.str())); JSON_THROW(parse_error::create(112, current_idx + 1, "error reading CBOR; last byte: 0x" + ss.str()));
} }
} }
} }
...@@ -9697,7 +9738,7 @@ class basic_json ...@@ -9697,7 +9738,7 @@ class basic_json
case basic_json::value_t::null: case basic_json::value_t::null:
{ {
JSON_THROW(invalid_iterator(214, "cannot get value")); JSON_THROW(invalid_iterator::create(214, "cannot get value"));
} }
default: default:
...@@ -9707,7 +9748,7 @@ class basic_json ...@@ -9707,7 +9748,7 @@ class basic_json
return *m_object; return *m_object;
} }
JSON_THROW(invalid_iterator(214, "cannot get value")); JSON_THROW(invalid_iterator::create(214, "cannot get value"));
} }
} }
} }
...@@ -9741,7 +9782,7 @@ class basic_json ...@@ -9741,7 +9782,7 @@ class basic_json
return m_object; return m_object;
} }
JSON_THROW(invalid_iterator(214, "cannot get value")); JSON_THROW(invalid_iterator::create(214, "cannot get value"));
} }
} }
} }
...@@ -9841,7 +9882,7 @@ class basic_json ...@@ -9841,7 +9882,7 @@ class basic_json
// if objects are not the same, the comparison is undefined // if objects are not the same, the comparison is undefined
if (m_object != other.m_object) if (m_object != other.m_object)
{ {
JSON_THROW(invalid_iterator(212, "cannot compare iterators of different containers")); JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
} }
assert(m_object != nullptr); assert(m_object != nullptr);
...@@ -9883,7 +9924,7 @@ class basic_json ...@@ -9883,7 +9924,7 @@ class basic_json
// if objects are not the same, the comparison is undefined // if objects are not the same, the comparison is undefined
if (m_object != other.m_object) if (m_object != other.m_object)
{ {
JSON_THROW(invalid_iterator(212, "cannot compare iterators of different containers")); JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
} }
assert(m_object != nullptr); assert(m_object != nullptr);
...@@ -9892,7 +9933,7 @@ class basic_json ...@@ -9892,7 +9933,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
JSON_THROW(invalid_iterator(213, "cannot compare order of object iterators")); JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
...@@ -9946,7 +9987,7 @@ class basic_json ...@@ -9946,7 +9987,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
JSON_THROW(invalid_iterator(209, "cannot use offsets with object iterators")); JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
...@@ -10008,7 +10049,7 @@ class basic_json ...@@ -10008,7 +10049,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
JSON_THROW(invalid_iterator(209, "cannot use offsets with object iterators")); JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
...@@ -10035,7 +10076,7 @@ class basic_json ...@@ -10035,7 +10076,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
JSON_THROW(invalid_iterator(208, "cannot use operator[] for object iterators")); JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
...@@ -10045,7 +10086,7 @@ class basic_json ...@@ -10045,7 +10086,7 @@ class basic_json
case basic_json::value_t::null: case basic_json::value_t::null:
{ {
JSON_THROW(invalid_iterator(214, "cannot get value")); JSON_THROW(invalid_iterator::create(214, "cannot get value"));
} }
default: default:
...@@ -10055,7 +10096,7 @@ class basic_json ...@@ -10055,7 +10096,7 @@ class basic_json
return *m_object; return *m_object;
} }
JSON_THROW(invalid_iterator(214, "cannot get value")); JSON_THROW(invalid_iterator::create(214, "cannot get value"));
} }
} }
} }
...@@ -10073,7 +10114,7 @@ class basic_json ...@@ -10073,7 +10114,7 @@ class basic_json
return m_it.object_iterator->first; return m_it.object_iterator->first;
} }
JSON_THROW(invalid_iterator(207, "cannot use key() for non-object iterators")); JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
} }
/*! /*!
...@@ -10263,7 +10304,7 @@ class basic_json ...@@ -10263,7 +10304,7 @@ class basic_json
// immediately abort if stream is erroneous // immediately abort if stream is erroneous
if (s.fail()) if (s.fail())
{ {
JSON_THROW(parse_error(111, 0, "bad input stream")); JSON_THROW(parse_error::create(111, 0, "bad input stream"));
} }
// fill buffer // fill buffer
...@@ -10330,7 +10371,7 @@ class basic_json ...@@ -10330,7 +10371,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(parse_error(102, get_position(), "missing or wrong low surrogate")); JSON_THROW(parse_error::create(102, get_position(), "missing or wrong low surrogate"));
} }
} }
...@@ -10364,7 +10405,7 @@ class basic_json ...@@ -10364,7 +10405,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(parse_error(103, get_position(), "code points above 0x10FFFF are invalid")); JSON_THROW(parse_error::create(103, get_position(), "code points above 0x10FFFF are invalid"));
} }
return result; return result;
...@@ -11560,7 +11601,7 @@ basic_json_parser_74: ...@@ -11560,7 +11601,7 @@ basic_json_parser_74:
// check if stream is still good // check if stream is still good
if (m_stream->fail()) if (m_stream->fail())
{ {
JSON_THROW(parse_error(111, 0, "bad input stream")); JSON_THROW(parse_error::create(111, 0, "bad input stream"));
} }
std::getline(*m_stream, m_line_buffer_tmp, '\n'); std::getline(*m_stream, m_line_buffer_tmp, '\n');
...@@ -11729,7 +11770,7 @@ basic_json_parser_74: ...@@ -11729,7 +11770,7 @@ basic_json_parser_74:
// make sure there is a subsequent unicode // make sure there is a subsequent unicode
if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u') if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u')
{ {
JSON_THROW(parse_error(102, get_position(), "missing low surrogate")); JSON_THROW(parse_error::create(102, get_position(), "missing low surrogate"));
} }
// get code yyyy from uxxxx\uyyyy // get code yyyy from uxxxx\uyyyy
...@@ -11742,7 +11783,7 @@ basic_json_parser_74: ...@@ -11742,7 +11783,7 @@ basic_json_parser_74:
else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF) else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF)
{ {
// we found a lone low surrogate // we found a lone low surrogate
JSON_THROW(parse_error(102, get_position(), "missing high surrogate")); JSON_THROW(parse_error::create(102, get_position(), "missing high surrogate"));
} }
else else
{ {
...@@ -11986,7 +12027,7 @@ basic_json_parser_74: ...@@ -11986,7 +12027,7 @@ basic_json_parser_74:
// throw in case of infinity or NAN // throw in case of infinity or NAN
if (not std::isfinite(result.m_value.number_float)) if (not std::isfinite(result.m_value.number_float))
{ {
JSON_THROW(out_of_range(406, "number overflow parsing '" + get_token_string() + "'")); JSON_THROW(out_of_range::create(406, "number overflow parsing '" + get_token_string() + "'"));
} }
return true; return true;
...@@ -12299,7 +12340,7 @@ basic_json_parser_74: ...@@ -12299,7 +12340,7 @@ basic_json_parser_74:
"'") : "'") :
lexer::token_type_name(last_token)); lexer::token_type_name(last_token));
error_msg += "; expected " + lexer::token_type_name(t); error_msg += "; expected " + lexer::token_type_name(t);
JSON_THROW(parse_error(101, m_lexer.get_position(), error_msg)); JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
} }
} }
...@@ -12314,7 +12355,7 @@ basic_json_parser_74: ...@@ -12314,7 +12355,7 @@ basic_json_parser_74:
error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() + error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() +
"'") : "'") :
lexer::token_type_name(last_token)); lexer::token_type_name(last_token));
JSON_THROW(parse_error(101, m_lexer.get_position(), error_msg)); JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
} }
} }
...@@ -12413,7 +12454,7 @@ basic_json_parser_74: ...@@ -12413,7 +12454,7 @@ basic_json_parser_74:
{ {
if (is_root()) if (is_root())
{ {
JSON_THROW(out_of_range(405, "JSON pointer has no parent")); JSON_THROW(out_of_range::create(405, "JSON pointer has no parent"));
} }
auto last = reference_tokens.back(); auto last = reference_tokens.back();
...@@ -12431,7 +12472,7 @@ basic_json_parser_74: ...@@ -12431,7 +12472,7 @@ basic_json_parser_74:
{ {
if (is_root()) if (is_root())
{ {
JSON_THROW(out_of_range(405, "JSON pointer has no parent")); JSON_THROW(out_of_range::create(405, "JSON pointer has no parent"));
} }
json_pointer result = *this; json_pointer result = *this;
...@@ -12488,7 +12529,7 @@ basic_json_parser_74: ...@@ -12488,7 +12529,7 @@ basic_json_parser_74:
} }
JSON_CATCH (std::invalid_argument&) JSON_CATCH (std::invalid_argument&)
{ {
JSON_THROW(parse_error(109, 0, "array index '" + reference_token + "' is not a number")); JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
} }
break; break;
} }
...@@ -12502,7 +12543,7 @@ basic_json_parser_74: ...@@ -12502,7 +12543,7 @@ basic_json_parser_74:
*/ */
default: default:
{ {
JSON_THROW(type_error(313, "invalid value to unflatten")); JSON_THROW(type_error::create(313, "invalid value to unflatten"));
} }
} }
} }
...@@ -12570,7 +12611,7 @@ basic_json_parser_74: ...@@ -12570,7 +12611,7 @@ basic_json_parser_74:
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (reference_token.size() > 1 and reference_token[0] == '0') if (reference_token.size() > 1 and reference_token[0] == '0')
{ {
JSON_THROW(parse_error(106, 0, "array index '" + reference_token + "' must not begin with '0'")); JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
} }
if (reference_token == "-") if (reference_token == "-")
...@@ -12587,7 +12628,7 @@ basic_json_parser_74: ...@@ -12587,7 +12628,7 @@ basic_json_parser_74:
} }
JSON_CATCH (std::invalid_argument&) JSON_CATCH (std::invalid_argument&)
{ {
JSON_THROW(parse_error(109, 0, "array index '" + reference_token + "' is not a number")); JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
} }
} }
break; break;
...@@ -12595,7 +12636,7 @@ basic_json_parser_74: ...@@ -12595,7 +12636,7 @@ basic_json_parser_74:
default: default:
{ {
JSON_THROW(out_of_range(404, "unresolved reference token '" + reference_token + "'")); JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
} }
} }
} }
...@@ -12627,7 +12668,7 @@ basic_json_parser_74: ...@@ -12627,7 +12668,7 @@ basic_json_parser_74:
if (reference_token == "-") if (reference_token == "-")
{ {
// "-" always fails the range check // "-" always fails the range check
JSON_THROW(out_of_range(402, "array index '-' (" + JSON_THROW(out_of_range::create(402, "array index '-' (" +
std::to_string(ptr->m_value.array->size()) + std::to_string(ptr->m_value.array->size()) +
") is out of range")); ") is out of range"));
} }
...@@ -12635,7 +12676,7 @@ basic_json_parser_74: ...@@ -12635,7 +12676,7 @@ basic_json_parser_74:
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (reference_token.size() > 1 and reference_token[0] == '0') if (reference_token.size() > 1 and reference_token[0] == '0')
{ {
JSON_THROW(parse_error(106, 0, "array index '" + reference_token + "' must not begin with '0'")); JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
} }
// note: at performs range check // note: at performs range check
...@@ -12645,14 +12686,14 @@ basic_json_parser_74: ...@@ -12645,14 +12686,14 @@ basic_json_parser_74:
} }
JSON_CATCH (std::invalid_argument&) JSON_CATCH (std::invalid_argument&)
{ {
JSON_THROW(parse_error(109, 0, "array index '" + reference_token + "' is not a number")); JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
} }
break; break;
} }
default: default:
{ {
JSON_THROW(out_of_range(404, "unresolved reference token '" + reference_token + "'")); JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
} }
} }
} }
...@@ -12691,7 +12732,7 @@ basic_json_parser_74: ...@@ -12691,7 +12732,7 @@ basic_json_parser_74:
if (reference_token == "-") if (reference_token == "-")
{ {
// "-" cannot be used for const access // "-" cannot be used for const access
JSON_THROW(out_of_range(402, "array index '-' (" + JSON_THROW(out_of_range::create(402, "array index '-' (" +
std::to_string(ptr->m_value.array->size()) + std::to_string(ptr->m_value.array->size()) +
") is out of range")); ") is out of range"));
} }
...@@ -12699,7 +12740,7 @@ basic_json_parser_74: ...@@ -12699,7 +12740,7 @@ basic_json_parser_74:
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (reference_token.size() > 1 and reference_token[0] == '0') if (reference_token.size() > 1 and reference_token[0] == '0')
{ {
JSON_THROW(parse_error(106, 0, "array index '" + reference_token + "' must not begin with '0'")); JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
} }
// use unchecked array access // use unchecked array access
...@@ -12709,14 +12750,14 @@ basic_json_parser_74: ...@@ -12709,14 +12750,14 @@ basic_json_parser_74:
} }
JSON_CATCH (std::invalid_argument&) JSON_CATCH (std::invalid_argument&)
{ {
JSON_THROW(parse_error(109, 0, "array index '" + reference_token + "' is not a number")); JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
} }
break; break;
} }
default: default:
{ {
JSON_THROW(out_of_range(404, "unresolved reference token '" + reference_token + "'")); JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
} }
} }
} }
...@@ -12748,7 +12789,7 @@ basic_json_parser_74: ...@@ -12748,7 +12789,7 @@ basic_json_parser_74:
if (reference_token == "-") if (reference_token == "-")
{ {
// "-" always fails the range check // "-" always fails the range check
JSON_THROW(out_of_range(402, "array index '-' (" + JSON_THROW(out_of_range::create(402, "array index '-' (" +
std::to_string(ptr->m_value.array->size()) + std::to_string(ptr->m_value.array->size()) +
") is out of range")); ") is out of range"));
} }
...@@ -12756,7 +12797,7 @@ basic_json_parser_74: ...@@ -12756,7 +12797,7 @@ basic_json_parser_74:
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (reference_token.size() > 1 and reference_token[0] == '0') if (reference_token.size() > 1 and reference_token[0] == '0')
{ {
JSON_THROW(parse_error(106, 0, "array index '" + reference_token + "' must not begin with '0'")); JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
} }
// note: at performs range check // note: at performs range check
...@@ -12766,14 +12807,14 @@ basic_json_parser_74: ...@@ -12766,14 +12807,14 @@ basic_json_parser_74:
} }
JSON_CATCH (std::invalid_argument&) JSON_CATCH (std::invalid_argument&)
{ {
JSON_THROW(parse_error(109, 0, "array index '" + reference_token + "' is not a number")); JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
} }
break; break;
} }
default: default:
{ {
JSON_THROW(out_of_range(404, "unresolved reference token '" + reference_token + "'")); JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
} }
} }
} }
...@@ -12803,7 +12844,7 @@ basic_json_parser_74: ...@@ -12803,7 +12844,7 @@ basic_json_parser_74:
// check if nonempty reference string begins with slash // check if nonempty reference string begins with slash
if (reference_string[0] != '/') if (reference_string[0] != '/')
{ {
JSON_THROW(parse_error(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'")); JSON_THROW(parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'"));
} }
// extract the reference tokens: // extract the reference tokens:
...@@ -12838,7 +12879,7 @@ basic_json_parser_74: ...@@ -12838,7 +12879,7 @@ basic_json_parser_74:
(reference_token[pos + 1] != '0' and (reference_token[pos + 1] != '0' and
reference_token[pos + 1] != '1')) reference_token[pos + 1] != '1'))
{ {
JSON_THROW(parse_error(108, 0, "escape character '~' must be followed with '0' or '1'")); JSON_THROW(parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
} }
} }
...@@ -12969,7 +13010,7 @@ basic_json_parser_74: ...@@ -12969,7 +13010,7 @@ basic_json_parser_74:
{ {
if (not value.is_object()) if (not value.is_object())
{ {
JSON_THROW(type_error(314, "only objects can be unflattened")); JSON_THROW(type_error::create(314, "only objects can be unflattened"));
} }
basic_json result; basic_json result;
...@@ -12979,7 +13020,7 @@ basic_json_parser_74: ...@@ -12979,7 +13020,7 @@ basic_json_parser_74:
{ {
if (not element.second.is_primitive()) if (not element.second.is_primitive())
{ {
JSON_THROW(type_error(315, "values in object must be primitive")); JSON_THROW(type_error::create(315, "values in object must be primitive"));
} }
// assign value to reference pointed to by JSON pointer; Note // assign value to reference pointed to by JSON pointer; Note
...@@ -13364,7 +13405,7 @@ basic_json_parser_74: ...@@ -13364,7 +13405,7 @@ basic_json_parser_74:
if (static_cast<size_type>(idx) > parent.size()) if (static_cast<size_type>(idx) > parent.size())
{ {
// avoid undefined behavior // avoid undefined behavior
JSON_THROW(out_of_range(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"));
} }
else else
{ {
...@@ -13402,7 +13443,7 @@ basic_json_parser_74: ...@@ -13402,7 +13443,7 @@ basic_json_parser_74:
} }
else else
{ {
JSON_THROW(out_of_range(403, "key '" + last_path + "' not found")); JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
} }
} }
else if (parent.is_array()) else if (parent.is_array())
...@@ -13415,7 +13456,7 @@ basic_json_parser_74: ...@@ -13415,7 +13456,7 @@ basic_json_parser_74:
// type check: top level value must be an array // type check: top level value must be an array
if (not json_patch.is_array()) if (not json_patch.is_array())
{ {
JSON_THROW(parse_error(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"));
} }
// iterate and apply the operations // iterate and apply the operations
...@@ -13435,13 +13476,13 @@ basic_json_parser_74: ...@@ -13435,13 +13476,13 @@ basic_json_parser_74:
// check if desired value is present // check if desired value is present
if (it == val.m_value.object->end()) if (it == val.m_value.object->end())
{ {
JSON_THROW(parse_error(105, 0, error_msg + " must have member '" + member + "'")); JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
} }
// check if result is of type string // check if result is of type string
if (string_type and not it->second.is_string()) if (string_type and not it->second.is_string())
{ {
JSON_THROW(parse_error(105, 0, error_msg + " must have string member '" + member + "'")); JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
} }
// no error: return value // no error: return value
...@@ -13451,7 +13492,7 @@ basic_json_parser_74: ...@@ -13451,7 +13492,7 @@ basic_json_parser_74:
// type check: every element of the array must be an object // type check: every element of the array must be an object
if (not val.is_object()) if (not val.is_object())
{ {
JSON_THROW(parse_error(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"));
} }
// collect mandatory members // collect mandatory members
...@@ -13524,7 +13565,7 @@ basic_json_parser_74: ...@@ -13524,7 +13565,7 @@ basic_json_parser_74:
// throw an exception if test fails // throw an exception if test fails
if (not success) if (not success)
{ {
JSON_THROW(other_error(501, "unsuccessful: " + val.dump())); JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
} }
break; break;
...@@ -13534,7 +13575,7 @@ basic_json_parser_74: ...@@ -13534,7 +13575,7 @@ basic_json_parser_74:
{ {
// op must be "add", "remove", "replace", "move", "copy", or // op must be "add", "remove", "replace", "move", "copy", or
// "test" // "test"
JSON_THROW(parse_error(105, 0, "operation value '" + op + "' is invalid")); JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
} }
} }
} }
......
...@@ -116,29 +116,34 @@ namespace detail ...@@ -116,29 +116,34 @@ namespace detail
Extension of std::exception objects with a member @a id for exception ids. Extension of std::exception objects with a member @a id for exception ids.
@note To have nothrow-copy-constructible exceptions, we inherit from
std::runtime_error which can cope with arbitrary-length error messages.
Intermediate strings are built with static functions and then passed to
the actual constructor.
@since version 3.0.0 @since version 3.0.0
*/ */
class exception : public std::exception class exception : public std::runtime_error
{ {
public: public:
/// create exception with id an explanatory string
exception(int id_, const std::string& ename, const std::string& what_arg_)
: id(id_),
what_arg("[json.exception." + ename + "." + std::to_string(id_) + "] " + what_arg_)
{}
/// returns the explanatory string /// returns the explanatory string
virtual const char* what() const noexcept override virtual const char* what() const noexcept override
{ {
return what_arg.c_str(); return std::runtime_error::what();
} }
/// the id of the exception /// the id of the exception
const int id; const int id;
private: protected:
/// the explanatory string exception(int id_, const char* what_arg)
const std::string what_arg; : std::runtime_error(what_arg), id(id_)
{}
static std::string name(const std::string& ename, int id_)
{
return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
}
}; };
/*! /*!
...@@ -184,14 +189,16 @@ class parse_error : public exception ...@@ -184,14 +189,16 @@ class parse_error : public exception
@param[in] id_ the id of the exception @param[in] id_ the id of the exception
@param[in] byte_ the byte index where the error occured (or 0 if @param[in] byte_ the byte index where the error occured (or 0 if
the position cannot be determined) the position cannot be determined)
@param[in] what_arg_ the explanatory string @param[in] what_arg the explanatory string
@return parse_error object
*/ */
parse_error(int id_, size_t byte_, const std::string& what_arg_) static parse_error create(int id_, size_t byte_, const std::string& what_arg)
: exception(id_, "parse_error", "parse error" + {
std::string w = exception::name("parse_error", id_) + "parse error" +
(byte_ != 0 ? (" at " + std::to_string(byte_)) : "") + (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
": " + what_arg_), ": " + what_arg;
byte(byte_) return parse_error(id_, byte_, w.c_str());
{} }
/*! /*!
@brief byte index of the parse error @brief byte index of the parse error
...@@ -204,6 +211,12 @@ class parse_error : public exception ...@@ -204,6 +211,12 @@ class parse_error : public exception
MessagePack). MessagePack).
*/ */
const size_t byte; const size_t byte;
private:
parse_error(int id_, size_t byte_, const char* what_arg)
: exception(id_, what_arg),
byte(byte_)
{}
}; };
/*! /*!
...@@ -233,8 +246,15 @@ json.exception.invalid_iterator.214 | cannot get value | Cannot get value for it ...@@ -233,8 +246,15 @@ json.exception.invalid_iterator.214 | cannot get value | Cannot get value for it
class invalid_iterator : public exception class invalid_iterator : public exception
{ {
public: public:
invalid_iterator(int id_, const std::string& what_arg_) static invalid_iterator create(int id_, const std::string& what_arg)
: exception(id_, "invalid_iterator", what_arg_) {
std::string w = exception::name("invalid_iterator", id_) + what_arg;
return invalid_iterator(id_, w.c_str());
}
private:
invalid_iterator(int id_, const char* what_arg)
: exception(id_, what_arg)
{} {}
}; };
...@@ -265,8 +285,15 @@ json.exception.type_error.315 | values in object must be primitive | The @ref un ...@@ -265,8 +285,15 @@ json.exception.type_error.315 | values in object must be primitive | The @ref un
class type_error : public exception class type_error : public exception
{ {
public: public:
type_error(int id_, const std::string& what_arg_) static type_error create(int id_, const std::string& what_arg)
: exception(id_, "type_error", what_arg_) {
std::string w = exception::name("type_error", id_) + what_arg;
return type_error(id_, w.c_str());
}
private:
type_error(int id_, const char* what_arg)
: exception(id_, what_arg)
{} {}
}; };
...@@ -289,8 +316,15 @@ json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed n ...@@ -289,8 +316,15 @@ json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed n
class out_of_range : public exception class out_of_range : public exception
{ {
public: public:
out_of_range(int id_, const std::string& what_arg_) static out_of_range create(int id_, const std::string& what_arg)
: exception(id_, "out_of_range", what_arg_) {
std::string w = exception::name("out_of_range", id_) + what_arg;
return out_of_range(id_, w.c_str());
}
private:
out_of_range(int id_, const char* what_arg)
: exception(id_, what_arg)
{} {}
}; };
...@@ -308,8 +342,15 @@ json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "valu ...@@ -308,8 +342,15 @@ json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "valu
class other_error : public exception class other_error : public exception
{ {
public: public:
other_error(int id_, const std::string& what_arg_) static other_error create(int id_, const std::string& what_arg)
: exception(id_, "other_error", what_arg_) {
std::string w = exception::name("other_error", id_) + what_arg;
return other_error(id_, w.c_str());
}
private:
other_error(int id_, const char* what_arg)
: exception(id_, what_arg)
{} {}
}; };
...@@ -841,7 +882,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) ...@@ -841,7 +882,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
} }
default: default:
{ {
JSON_THROW(type_error(302, "type must be number, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be number, but is " + j.type_name()));
} }
} }
} }
...@@ -851,7 +892,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) ...@@ -851,7 +892,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
{ {
if (not j.is_boolean()) if (not j.is_boolean())
{ {
JSON_THROW(type_error(302, "type must be boolean, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be boolean, but is " + j.type_name()));
} }
b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>(); b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
} }
...@@ -861,7 +902,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) ...@@ -861,7 +902,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
{ {
if (not j.is_string()) if (not j.is_string())
{ {
JSON_THROW(type_error(302, "type must be string, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be string, but is " + j.type_name()));
} }
s = *j.template get_ptr<const typename BasicJsonType::string_t*>(); s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
} }
...@@ -898,7 +939,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr) ...@@ -898,7 +939,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
{ {
if (not j.is_array()) if (not j.is_array())
{ {
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be array, but is " + j.type_name()));
} }
arr = *j.template get_ptr<const typename BasicJsonType::array_t*>(); arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
} }
...@@ -910,7 +951,7 @@ void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l) ...@@ -910,7 +951,7 @@ void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
{ {
if (not j.is_array()) if (not j.is_array())
{ {
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be array, but is " + j.type_name()));
} }
for (auto it = j.rbegin(), end = j.rend(); it != end; ++it) for (auto it = j.rbegin(), end = j.rend(); it != end; ++it)
...@@ -961,7 +1002,7 @@ void from_json(const BasicJsonType& j, CompatibleArrayType& arr) ...@@ -961,7 +1002,7 @@ void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
{ {
if (not j.is_array()) if (not j.is_array())
{ {
JSON_THROW(type_error(302, "type must be array, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be array, but is " + j.type_name()));
} }
from_json_array_impl(j, arr, priority_tag<1> {}); from_json_array_impl(j, arr, priority_tag<1> {});
...@@ -973,7 +1014,7 @@ void from_json(const BasicJsonType& j, CompatibleObjectType& obj) ...@@ -973,7 +1014,7 @@ void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
{ {
if (not j.is_object()) if (not j.is_object())
{ {
JSON_THROW(type_error(302, "type must be object, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be object, but is " + j.type_name()));
} }
auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>(); auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
...@@ -1023,7 +1064,7 @@ void from_json(const BasicJsonType& j, ArithmeticType& val) ...@@ -1023,7 +1064,7 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
} }
default: default:
{ {
JSON_THROW(type_error(302, "type must be number, but is " + j.type_name())); JSON_THROW(type_error::create(302, "type must be number, but is " + j.type_name()));
} }
} }
} }
...@@ -1970,7 +2011,7 @@ class basic_json ...@@ -1970,7 +2011,7 @@ class basic_json
{ {
if (t == value_t::null) if (t == value_t::null)
{ {
JSON_THROW(other_error(500, "961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE
} }
break; break;
} }
...@@ -2325,7 +2366,7 @@ class basic_json ...@@ -2325,7 +2366,7 @@ class basic_json
// if object is wanted but impossible, throw an exception // if object is wanted but impossible, throw an exception
if (manual_type == value_t::object and not is_an_object) if (manual_type == value_t::object and not is_an_object)
{ {
JSON_THROW(type_error(301, "cannot create object from initializer list")); JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
} }
} }
...@@ -2509,7 +2550,7 @@ class basic_json ...@@ -2509,7 +2550,7 @@ class basic_json
// make sure iterator fits the current value // make sure iterator fits the current value
if (first.m_object != last.m_object) if (first.m_object != last.m_object)
{ {
JSON_THROW(invalid_iterator(201, "iterators are not compatible")); JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
} }
// copy type from first iterator // copy type from first iterator
...@@ -2526,7 +2567,7 @@ class basic_json ...@@ -2526,7 +2567,7 @@ class basic_json
{ {
if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end()) if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
{ {
JSON_THROW(invalid_iterator(204, "iterators out of range")); JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
} }
break; break;
} }
...@@ -2585,7 +2626,7 @@ class basic_json ...@@ -2585,7 +2626,7 @@ class basic_json
default: default:
{ {
JSON_THROW(invalid_iterator(206, "cannot construct with iterators from " + JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
first.m_object->type_name())); first.m_object->type_name()));
} }
} }
...@@ -3224,7 +3265,7 @@ class basic_json ...@@ -3224,7 +3265,7 @@ class basic_json
return m_value.boolean; return m_value.boolean;
} }
JSON_THROW(type_error(302, "type must be boolean, but is " + type_name())); JSON_THROW(type_error::create(302, "type must be boolean, but is " + type_name()));
} }
/// get a pointer to the value (object) /// get a pointer to the value (object)
...@@ -3336,7 +3377,7 @@ class basic_json ...@@ -3336,7 +3377,7 @@ class basic_json
return *ptr; return *ptr;
} }
JSON_THROW(type_error(303, "incompatible ReferenceType for get_ref, actual type is " + obj.type_name())); JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + obj.type_name()));
} }
public: public:
...@@ -3738,12 +3779,12 @@ class basic_json ...@@ -3738,12 +3779,12 @@ class basic_json
JSON_CATCH (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
JSON_THROW(out_of_range(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"));
} }
} }
else else
{ {
JSON_THROW(type_error(304, "cannot use at() with " + type_name())); JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
} }
} }
...@@ -3785,12 +3826,12 @@ class basic_json ...@@ -3785,12 +3826,12 @@ class basic_json
JSON_CATCH (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
JSON_THROW(out_of_range(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"));
} }
} }
else else
{ {
JSON_THROW(type_error(304, "cannot use at() with " + type_name())); JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
} }
} }
...@@ -3836,12 +3877,12 @@ class basic_json ...@@ -3836,12 +3877,12 @@ class basic_json
JSON_CATCH (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
JSON_THROW(out_of_range(403, "key '" + key + "' not found")); JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
} }
} }
else else
{ {
JSON_THROW(type_error(304, "cannot use at() with " + type_name())); JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
} }
} }
...@@ -3887,12 +3928,12 @@ class basic_json ...@@ -3887,12 +3928,12 @@ class basic_json
JSON_CATCH (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
JSON_THROW(out_of_range(403, "key '" + key + "' not found")); JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
} }
} }
else else
{ {
JSON_THROW(type_error(304, "cannot use at() with " + type_name())); JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
} }
} }
...@@ -3945,7 +3986,7 @@ class basic_json ...@@ -3945,7 +3986,7 @@ class basic_json
return m_value.array->operator[](idx); return m_value.array->operator[](idx);
} }
JSON_THROW(type_error(305, "cannot use operator[] with " + type_name())); JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
} }
/*! /*!
...@@ -3975,7 +4016,7 @@ class basic_json ...@@ -3975,7 +4016,7 @@ class basic_json
return m_value.array->operator[](idx); return m_value.array->operator[](idx);
} }
JSON_THROW(type_error(305, "cannot use operator[] with " + type_name())); JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
} }
/*! /*!
...@@ -4021,7 +4062,7 @@ class basic_json ...@@ -4021,7 +4062,7 @@ class basic_json
return m_value.object->operator[](key); return m_value.object->operator[](key);
} }
JSON_THROW(type_error(305, "cannot use operator[] with " + type_name())); JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
} }
/*! /*!
...@@ -4063,7 +4104,7 @@ class basic_json ...@@ -4063,7 +4104,7 @@ class basic_json
return m_value.object->find(key)->second; return m_value.object->find(key)->second;
} }
JSON_THROW(type_error(305, "cannot use operator[] with " + type_name())); JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
} }
/*! /*!
...@@ -4178,7 +4219,7 @@ class basic_json ...@@ -4178,7 +4219,7 @@ class basic_json
return m_value.object->operator[](key); return m_value.object->operator[](key);
} }
JSON_THROW(type_error(305, "cannot use operator[] with " + type_name())); JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
} }
/*! /*!
...@@ -4221,7 +4262,7 @@ class basic_json ...@@ -4221,7 +4262,7 @@ class basic_json
return m_value.object->find(key)->second; return m_value.object->find(key)->second;
} }
JSON_THROW(type_error(305, "cannot use operator[] with " + type_name())); JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
} }
/*! /*!
...@@ -4290,7 +4331,7 @@ class basic_json ...@@ -4290,7 +4331,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(type_error(306, "cannot use value() with " + type_name())); JSON_THROW(type_error::create(306, "cannot use value() with " + type_name()));
} }
} }
...@@ -4362,7 +4403,7 @@ class basic_json ...@@ -4362,7 +4403,7 @@ class basic_json
} }
} }
JSON_THROW(type_error(306, "cannot use value() with " + type_name())); JSON_THROW(type_error::create(306, "cannot use value() with " + type_name()));
} }
/*! /*!
...@@ -4515,7 +4556,7 @@ class basic_json ...@@ -4515,7 +4556,7 @@ class basic_json
// make sure iterator fits the current value // make sure iterator fits the current value
if (this != pos.m_object) if (this != pos.m_object)
{ {
JSON_THROW(invalid_iterator(202, "iterator does not fit current value")); JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
} }
IteratorType result = end(); IteratorType result = end();
...@@ -4530,7 +4571,7 @@ class basic_json ...@@ -4530,7 +4571,7 @@ class basic_json
{ {
if (not pos.m_it.primitive_iterator.is_begin()) if (not pos.m_it.primitive_iterator.is_begin())
{ {
JSON_THROW(invalid_iterator(205, "iterator out of range")); JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
} }
if (is_string()) if (is_string())
...@@ -4560,7 +4601,7 @@ class basic_json ...@@ -4560,7 +4601,7 @@ class basic_json
default: default:
{ {
JSON_THROW(type_error(307, "cannot use erase() with " + type_name())); JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
} }
} }
...@@ -4622,7 +4663,7 @@ class basic_json ...@@ -4622,7 +4663,7 @@ class basic_json
// make sure iterator fits the current value // make sure iterator fits the current value
if (this != first.m_object or this != last.m_object) if (this != first.m_object or this != last.m_object)
{ {
JSON_THROW(invalid_iterator(203, "iterators do not fit current value")); JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
} }
IteratorType result = end(); IteratorType result = end();
...@@ -4637,7 +4678,7 @@ class basic_json ...@@ -4637,7 +4678,7 @@ class basic_json
{ {
if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end()) if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
{ {
JSON_THROW(invalid_iterator(204, "iterators out of range")); JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
} }
if (is_string()) if (is_string())
...@@ -4669,7 +4710,7 @@ class basic_json ...@@ -4669,7 +4710,7 @@ class basic_json
default: default:
{ {
JSON_THROW(type_error(307, "cannot use erase() with " + type_name())); JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
} }
} }
...@@ -4713,7 +4754,7 @@ class basic_json ...@@ -4713,7 +4754,7 @@ class basic_json
return m_value.object->erase(key); return m_value.object->erase(key);
} }
JSON_THROW(type_error(307, "cannot use erase() with " + type_name())); JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
} }
/*! /*!
...@@ -4747,14 +4788,14 @@ class basic_json ...@@ -4747,14 +4788,14 @@ class basic_json
{ {
if (idx >= size()) if (idx >= size())
{ {
JSON_THROW(out_of_range(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"));
} }
m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx)); m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
} }
else else
{ {
JSON_THROW(type_error(307, "cannot use erase() with " + type_name())); JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
} }
} }
...@@ -5472,7 +5513,7 @@ class basic_json ...@@ -5472,7 +5513,7 @@ class basic_json
// push_back only works for null objects or arrays // push_back only works for null objects or arrays
if (not(is_null() or is_array())) if (not(is_null() or is_array()))
{ {
JSON_THROW(type_error(308, "cannot use push_back() with " + type_name())); JSON_THROW(type_error::create(308, "cannot use push_back() with " + type_name()));
} }
// transform null object into an array // transform null object into an array
...@@ -5508,7 +5549,7 @@ class basic_json ...@@ -5508,7 +5549,7 @@ class basic_json
// push_back only works for null objects or arrays // push_back only works for null objects or arrays
if (not(is_null() or is_array())) if (not(is_null() or is_array()))
{ {
JSON_THROW(type_error(308, "cannot use push_back() with " + type_name())); JSON_THROW(type_error::create(308, "cannot use push_back() with " + type_name()));
} }
// transform null object into an array // transform null object into an array
...@@ -5558,7 +5599,7 @@ class basic_json ...@@ -5558,7 +5599,7 @@ class basic_json
// push_back only works for null objects or objects // push_back only works for null objects or objects
if (not(is_null() or is_object())) if (not(is_null() or is_object()))
{ {
JSON_THROW(type_error(308, "cannot use push_back() with " + type_name())); JSON_THROW(type_error::create(308, "cannot use push_back() with " + type_name()));
} }
// transform null object into an object // transform null object into an object
...@@ -5658,7 +5699,7 @@ class basic_json ...@@ -5658,7 +5699,7 @@ class basic_json
// emplace_back only works for null objects or arrays // emplace_back only works for null objects or arrays
if (not(is_null() or is_array())) if (not(is_null() or is_array()))
{ {
JSON_THROW(type_error(311, "cannot use emplace_back() with " + type_name())); JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + type_name()));
} }
// transform null object into an array // transform null object into an array
...@@ -5706,7 +5747,7 @@ class basic_json ...@@ -5706,7 +5747,7 @@ class basic_json
// emplace only works for null objects or arrays // emplace only works for null objects or arrays
if (not(is_null() or is_object())) if (not(is_null() or is_object()))
{ {
JSON_THROW(type_error(311, "cannot use emplace() with " + type_name())); JSON_THROW(type_error::create(311, "cannot use emplace() with " + type_name()));
} }
// transform null object into an object // transform null object into an object
...@@ -5757,7 +5798,7 @@ class basic_json ...@@ -5757,7 +5798,7 @@ class basic_json
// check if iterator pos fits to this JSON value // check if iterator pos fits to this JSON value
if (pos.m_object != this) if (pos.m_object != this)
{ {
JSON_THROW(invalid_iterator(202, "iterator does not fit current value")); JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
} }
// insert to array and return iterator // insert to array and return iterator
...@@ -5766,7 +5807,7 @@ class basic_json ...@@ -5766,7 +5807,7 @@ class basic_json
return result; return result;
} }
JSON_THROW(type_error(309, "cannot use insert() with " + type_name())); JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
} }
/*! /*!
...@@ -5810,7 +5851,7 @@ class basic_json ...@@ -5810,7 +5851,7 @@ class basic_json
// check if iterator pos fits to this JSON value // check if iterator pos fits to this JSON value
if (pos.m_object != this) if (pos.m_object != this)
{ {
JSON_THROW(invalid_iterator(202, "iterator does not fit current value")); JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
} }
// insert to array and return iterator // insert to array and return iterator
...@@ -5819,7 +5860,7 @@ class basic_json ...@@ -5819,7 +5860,7 @@ class basic_json
return result; return result;
} }
JSON_THROW(type_error(309, "cannot use insert() with " + type_name())); JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
} }
/*! /*!
...@@ -5857,24 +5898,24 @@ class basic_json ...@@ -5857,24 +5898,24 @@ class basic_json
// insert only works for arrays // insert only works for arrays
if (not is_array()) if (not is_array())
{ {
JSON_THROW(type_error(309, "cannot use insert() with " + type_name())); JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
} }
// check if iterator pos fits to this JSON value // check if iterator pos fits to this JSON value
if (pos.m_object != this) if (pos.m_object != this)
{ {
JSON_THROW(invalid_iterator(202, "iterator does not fit current value")); JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
} }
// check if range iterators belong to the same JSON object // check if range iterators belong to the same JSON object
if (first.m_object != last.m_object) if (first.m_object != last.m_object)
{ {
JSON_THROW(invalid_iterator(210, "iterators do not fit")); JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
} }
if (first.m_object == this or last.m_object == this) if (first.m_object == this or last.m_object == this)
{ {
JSON_THROW(invalid_iterator(211, "passed iterators may not belong to container")); JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
} }
// insert to array and return iterator // insert to array and return iterator
...@@ -5915,13 +5956,13 @@ class basic_json ...@@ -5915,13 +5956,13 @@ class basic_json
// insert only works for arrays // insert only works for arrays
if (not is_array()) if (not is_array())
{ {
JSON_THROW(type_error(309, "cannot use insert() with " + type_name())); JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
} }
// check if iterator pos fits to this JSON value // check if iterator pos fits to this JSON value
if (pos.m_object != this) if (pos.m_object != this)
{ {
JSON_THROW(invalid_iterator(202, "iterator does not fit current value")); JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
} }
// insert to array and return iterator // insert to array and return iterator
...@@ -5988,7 +6029,7 @@ class basic_json ...@@ -5988,7 +6029,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(type_error(310, "cannot use swap() with " + type_name())); JSON_THROW(type_error::create(310, "cannot use swap() with " + type_name()));
} }
} }
...@@ -6021,7 +6062,7 @@ class basic_json ...@@ -6021,7 +6062,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(type_error(310, "cannot use swap() with " + type_name())); JSON_THROW(type_error::create(310, "cannot use swap() with " + type_name()));
} }
} }
...@@ -6054,7 +6095,7 @@ class basic_json ...@@ -6054,7 +6095,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(type_error(310, "cannot use swap() with " + type_name())); JSON_THROW(type_error::create(310, "cannot use swap() with " + type_name()));
} }
} }
...@@ -7999,19 +8040,19 @@ class basic_json ...@@ -7999,19 +8040,19 @@ class basic_json
// simple case: requested length is greater than the vector's length // simple case: requested length is greater than the vector's length
if (len > size or offset > size) if (len > size or offset > size)
{ {
JSON_THROW(parse_error(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector")); JSON_THROW(parse_error::create(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector"));
} }
// second case: adding offset would result in overflow // second case: adding offset would result in overflow
if ((size > ((std::numeric_limits<size_t>::max)() - offset))) if ((size > ((std::numeric_limits<size_t>::max)() - offset)))
{ {
JSON_THROW(parse_error(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector")); JSON_THROW(parse_error::create(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector"));
} }
// last case: reading past the end of the vector // last case: reading past the end of the vector
if (len + offset > size) if (len + offset > size)
{ {
JSON_THROW(parse_error(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector")); JSON_THROW(parse_error::create(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector"));
} }
} }
...@@ -8043,7 +8084,7 @@ class basic_json ...@@ -8043,7 +8084,7 @@ class basic_json
std::stringstream ss; std::stringstream ss;
ss << std::hex << static_cast<int>(v[idx]); ss << std::hex << static_cast<int>(v[idx]);
JSON_THROW(parse_error(113, idx + 1, "expected a MessagePack string; last byte: 0x" + ss.str())); JSON_THROW(parse_error::create(113, idx + 1, "expected a MessagePack string; last byte: 0x" + ss.str()));
} }
/*! /*!
...@@ -8073,7 +8114,7 @@ class basic_json ...@@ -8073,7 +8114,7 @@ class basic_json
std::stringstream ss; std::stringstream ss;
ss << std::hex << static_cast<int>(v[idx]); ss << std::hex << static_cast<int>(v[idx]);
JSON_THROW(parse_error(113, idx + 1, "expected a CBOR string; last byte: 0x" + ss.str())); JSON_THROW(parse_error::create(113, idx + 1, "expected a CBOR string; last byte: 0x" + ss.str()));
} }
/*! /*!
...@@ -8316,7 +8357,7 @@ class basic_json ...@@ -8316,7 +8357,7 @@ class basic_json
{ {
std::stringstream ss; std::stringstream ss;
ss << std::hex << static_cast<int>(v[current_idx]); ss << std::hex << static_cast<int>(v[current_idx]);
JSON_THROW(parse_error(112, current_idx + 1, "error reading MessagePack; last byte: 0x" + ss.str())); JSON_THROW(parse_error::create(112, current_idx + 1, "error reading MessagePack; last byte: 0x" + ss.str()));
} }
} }
} }
...@@ -8816,7 +8857,7 @@ class basic_json ...@@ -8816,7 +8857,7 @@ class basic_json
{ {
std::stringstream ss; std::stringstream ss;
ss << std::hex << static_cast<int>(v[current_idx]); ss << std::hex << static_cast<int>(v[current_idx]);
JSON_THROW(parse_error(112, current_idx + 1, "error reading CBOR; last byte: 0x" + ss.str())); JSON_THROW(parse_error::create(112, current_idx + 1, "error reading CBOR; last byte: 0x" + ss.str()));
} }
} }
} }
...@@ -9697,7 +9738,7 @@ class basic_json ...@@ -9697,7 +9738,7 @@ class basic_json
case basic_json::value_t::null: case basic_json::value_t::null:
{ {
JSON_THROW(invalid_iterator(214, "cannot get value")); JSON_THROW(invalid_iterator::create(214, "cannot get value"));
} }
default: default:
...@@ -9707,7 +9748,7 @@ class basic_json ...@@ -9707,7 +9748,7 @@ class basic_json
return *m_object; return *m_object;
} }
JSON_THROW(invalid_iterator(214, "cannot get value")); JSON_THROW(invalid_iterator::create(214, "cannot get value"));
} }
} }
} }
...@@ -9741,7 +9782,7 @@ class basic_json ...@@ -9741,7 +9782,7 @@ class basic_json
return m_object; return m_object;
} }
JSON_THROW(invalid_iterator(214, "cannot get value")); JSON_THROW(invalid_iterator::create(214, "cannot get value"));
} }
} }
} }
...@@ -9841,7 +9882,7 @@ class basic_json ...@@ -9841,7 +9882,7 @@ class basic_json
// if objects are not the same, the comparison is undefined // if objects are not the same, the comparison is undefined
if (m_object != other.m_object) if (m_object != other.m_object)
{ {
JSON_THROW(invalid_iterator(212, "cannot compare iterators of different containers")); JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
} }
assert(m_object != nullptr); assert(m_object != nullptr);
...@@ -9883,7 +9924,7 @@ class basic_json ...@@ -9883,7 +9924,7 @@ class basic_json
// if objects are not the same, the comparison is undefined // if objects are not the same, the comparison is undefined
if (m_object != other.m_object) if (m_object != other.m_object)
{ {
JSON_THROW(invalid_iterator(212, "cannot compare iterators of different containers")); JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
} }
assert(m_object != nullptr); assert(m_object != nullptr);
...@@ -9892,7 +9933,7 @@ class basic_json ...@@ -9892,7 +9933,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
JSON_THROW(invalid_iterator(213, "cannot compare order of object iterators")); JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
...@@ -9946,7 +9987,7 @@ class basic_json ...@@ -9946,7 +9987,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
JSON_THROW(invalid_iterator(209, "cannot use offsets with object iterators")); JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
...@@ -10008,7 +10049,7 @@ class basic_json ...@@ -10008,7 +10049,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
JSON_THROW(invalid_iterator(209, "cannot use offsets with object iterators")); JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
...@@ -10035,7 +10076,7 @@ class basic_json ...@@ -10035,7 +10076,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
JSON_THROW(invalid_iterator(208, "cannot use operator[] for object iterators")); JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
...@@ -10045,7 +10086,7 @@ class basic_json ...@@ -10045,7 +10086,7 @@ class basic_json
case basic_json::value_t::null: case basic_json::value_t::null:
{ {
JSON_THROW(invalid_iterator(214, "cannot get value")); JSON_THROW(invalid_iterator::create(214, "cannot get value"));
} }
default: default:
...@@ -10055,7 +10096,7 @@ class basic_json ...@@ -10055,7 +10096,7 @@ class basic_json
return *m_object; return *m_object;
} }
JSON_THROW(invalid_iterator(214, "cannot get value")); JSON_THROW(invalid_iterator::create(214, "cannot get value"));
} }
} }
} }
...@@ -10073,7 +10114,7 @@ class basic_json ...@@ -10073,7 +10114,7 @@ class basic_json
return m_it.object_iterator->first; return m_it.object_iterator->first;
} }
JSON_THROW(invalid_iterator(207, "cannot use key() for non-object iterators")); JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
} }
/*! /*!
...@@ -10263,7 +10304,7 @@ class basic_json ...@@ -10263,7 +10304,7 @@ class basic_json
// immediately abort if stream is erroneous // immediately abort if stream is erroneous
if (s.fail()) if (s.fail())
{ {
JSON_THROW(parse_error(111, 0, "bad input stream")); JSON_THROW(parse_error::create(111, 0, "bad input stream"));
} }
// fill buffer // fill buffer
...@@ -10330,7 +10371,7 @@ class basic_json ...@@ -10330,7 +10371,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(parse_error(102, get_position(), "missing or wrong low surrogate")); JSON_THROW(parse_error::create(102, get_position(), "missing or wrong low surrogate"));
} }
} }
...@@ -10364,7 +10405,7 @@ class basic_json ...@@ -10364,7 +10405,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(parse_error(103, get_position(), "code points above 0x10FFFF are invalid")); JSON_THROW(parse_error::create(103, get_position(), "code points above 0x10FFFF are invalid"));
} }
return result; return result;
...@@ -10593,7 +10634,7 @@ class basic_json ...@@ -10593,7 +10634,7 @@ class basic_json
// check if stream is still good // check if stream is still good
if (m_stream->fail()) if (m_stream->fail())
{ {
JSON_THROW(parse_error(111, 0, "bad input stream")); JSON_THROW(parse_error::create(111, 0, "bad input stream"));
} }
std::getline(*m_stream, m_line_buffer_tmp, '\n'); std::getline(*m_stream, m_line_buffer_tmp, '\n');
...@@ -10762,7 +10803,7 @@ class basic_json ...@@ -10762,7 +10803,7 @@ class basic_json
// make sure there is a subsequent unicode // make sure there is a subsequent unicode
if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u') if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u')
{ {
JSON_THROW(parse_error(102, get_position(), "missing low surrogate")); JSON_THROW(parse_error::create(102, get_position(), "missing low surrogate"));
} }
// get code yyyy from uxxxx\uyyyy // get code yyyy from uxxxx\uyyyy
...@@ -10775,7 +10816,7 @@ class basic_json ...@@ -10775,7 +10816,7 @@ class basic_json
else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF) else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF)
{ {
// we found a lone low surrogate // we found a lone low surrogate
JSON_THROW(parse_error(102, get_position(), "missing high surrogate")); JSON_THROW(parse_error::create(102, get_position(), "missing high surrogate"));
} }
else else
{ {
...@@ -11019,7 +11060,7 @@ class basic_json ...@@ -11019,7 +11060,7 @@ class basic_json
// throw in case of infinity or NAN // throw in case of infinity or NAN
if (not std::isfinite(result.m_value.number_float)) if (not std::isfinite(result.m_value.number_float))
{ {
JSON_THROW(out_of_range(406, "number overflow parsing '" + get_token_string() + "'")); JSON_THROW(out_of_range::create(406, "number overflow parsing '" + get_token_string() + "'"));
} }
return true; return true;
...@@ -11332,7 +11373,7 @@ class basic_json ...@@ -11332,7 +11373,7 @@ class basic_json
"'") : "'") :
lexer::token_type_name(last_token)); lexer::token_type_name(last_token));
error_msg += "; expected " + lexer::token_type_name(t); error_msg += "; expected " + lexer::token_type_name(t);
JSON_THROW(parse_error(101, m_lexer.get_position(), error_msg)); JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
} }
} }
...@@ -11347,7 +11388,7 @@ class basic_json ...@@ -11347,7 +11388,7 @@ class basic_json
error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() + error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() +
"'") : "'") :
lexer::token_type_name(last_token)); lexer::token_type_name(last_token));
JSON_THROW(parse_error(101, m_lexer.get_position(), error_msg)); JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
} }
} }
...@@ -11446,7 +11487,7 @@ class basic_json ...@@ -11446,7 +11487,7 @@ class basic_json
{ {
if (is_root()) if (is_root())
{ {
JSON_THROW(out_of_range(405, "JSON pointer has no parent")); JSON_THROW(out_of_range::create(405, "JSON pointer has no parent"));
} }
auto last = reference_tokens.back(); auto last = reference_tokens.back();
...@@ -11464,7 +11505,7 @@ class basic_json ...@@ -11464,7 +11505,7 @@ class basic_json
{ {
if (is_root()) if (is_root())
{ {
JSON_THROW(out_of_range(405, "JSON pointer has no parent")); JSON_THROW(out_of_range::create(405, "JSON pointer has no parent"));
} }
json_pointer result = *this; json_pointer result = *this;
...@@ -11521,7 +11562,7 @@ class basic_json ...@@ -11521,7 +11562,7 @@ class basic_json
} }
JSON_CATCH (std::invalid_argument&) JSON_CATCH (std::invalid_argument&)
{ {
JSON_THROW(parse_error(109, 0, "array index '" + reference_token + "' is not a number")); JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
} }
break; break;
} }
...@@ -11535,7 +11576,7 @@ class basic_json ...@@ -11535,7 +11576,7 @@ class basic_json
*/ */
default: default:
{ {
JSON_THROW(type_error(313, "invalid value to unflatten")); JSON_THROW(type_error::create(313, "invalid value to unflatten"));
} }
} }
} }
...@@ -11603,7 +11644,7 @@ class basic_json ...@@ -11603,7 +11644,7 @@ class basic_json
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (reference_token.size() > 1 and reference_token[0] == '0') if (reference_token.size() > 1 and reference_token[0] == '0')
{ {
JSON_THROW(parse_error(106, 0, "array index '" + reference_token + "' must not begin with '0'")); JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
} }
if (reference_token == "-") if (reference_token == "-")
...@@ -11620,7 +11661,7 @@ class basic_json ...@@ -11620,7 +11661,7 @@ class basic_json
} }
JSON_CATCH (std::invalid_argument&) JSON_CATCH (std::invalid_argument&)
{ {
JSON_THROW(parse_error(109, 0, "array index '" + reference_token + "' is not a number")); JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
} }
} }
break; break;
...@@ -11628,7 +11669,7 @@ class basic_json ...@@ -11628,7 +11669,7 @@ class basic_json
default: default:
{ {
JSON_THROW(out_of_range(404, "unresolved reference token '" + reference_token + "'")); JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
} }
} }
} }
...@@ -11660,7 +11701,7 @@ class basic_json ...@@ -11660,7 +11701,7 @@ class basic_json
if (reference_token == "-") if (reference_token == "-")
{ {
// "-" always fails the range check // "-" always fails the range check
JSON_THROW(out_of_range(402, "array index '-' (" + JSON_THROW(out_of_range::create(402, "array index '-' (" +
std::to_string(ptr->m_value.array->size()) + std::to_string(ptr->m_value.array->size()) +
") is out of range")); ") is out of range"));
} }
...@@ -11668,7 +11709,7 @@ class basic_json ...@@ -11668,7 +11709,7 @@ class basic_json
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (reference_token.size() > 1 and reference_token[0] == '0') if (reference_token.size() > 1 and reference_token[0] == '0')
{ {
JSON_THROW(parse_error(106, 0, "array index '" + reference_token + "' must not begin with '0'")); JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
} }
// note: at performs range check // note: at performs range check
...@@ -11678,14 +11719,14 @@ class basic_json ...@@ -11678,14 +11719,14 @@ class basic_json
} }
JSON_CATCH (std::invalid_argument&) JSON_CATCH (std::invalid_argument&)
{ {
JSON_THROW(parse_error(109, 0, "array index '" + reference_token + "' is not a number")); JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
} }
break; break;
} }
default: default:
{ {
JSON_THROW(out_of_range(404, "unresolved reference token '" + reference_token + "'")); JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
} }
} }
} }
...@@ -11724,7 +11765,7 @@ class basic_json ...@@ -11724,7 +11765,7 @@ class basic_json
if (reference_token == "-") if (reference_token == "-")
{ {
// "-" cannot be used for const access // "-" cannot be used for const access
JSON_THROW(out_of_range(402, "array index '-' (" + JSON_THROW(out_of_range::create(402, "array index '-' (" +
std::to_string(ptr->m_value.array->size()) + std::to_string(ptr->m_value.array->size()) +
") is out of range")); ") is out of range"));
} }
...@@ -11732,7 +11773,7 @@ class basic_json ...@@ -11732,7 +11773,7 @@ class basic_json
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (reference_token.size() > 1 and reference_token[0] == '0') if (reference_token.size() > 1 and reference_token[0] == '0')
{ {
JSON_THROW(parse_error(106, 0, "array index '" + reference_token + "' must not begin with '0'")); JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
} }
// use unchecked array access // use unchecked array access
...@@ -11742,14 +11783,14 @@ class basic_json ...@@ -11742,14 +11783,14 @@ class basic_json
} }
JSON_CATCH (std::invalid_argument&) JSON_CATCH (std::invalid_argument&)
{ {
JSON_THROW(parse_error(109, 0, "array index '" + reference_token + "' is not a number")); JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
} }
break; break;
} }
default: default:
{ {
JSON_THROW(out_of_range(404, "unresolved reference token '" + reference_token + "'")); JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
} }
} }
} }
...@@ -11781,7 +11822,7 @@ class basic_json ...@@ -11781,7 +11822,7 @@ class basic_json
if (reference_token == "-") if (reference_token == "-")
{ {
// "-" always fails the range check // "-" always fails the range check
JSON_THROW(out_of_range(402, "array index '-' (" + JSON_THROW(out_of_range::create(402, "array index '-' (" +
std::to_string(ptr->m_value.array->size()) + std::to_string(ptr->m_value.array->size()) +
") is out of range")); ") is out of range"));
} }
...@@ -11789,7 +11830,7 @@ class basic_json ...@@ -11789,7 +11830,7 @@ class basic_json
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (reference_token.size() > 1 and reference_token[0] == '0') if (reference_token.size() > 1 and reference_token[0] == '0')
{ {
JSON_THROW(parse_error(106, 0, "array index '" + reference_token + "' must not begin with '0'")); JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
} }
// note: at performs range check // note: at performs range check
...@@ -11799,14 +11840,14 @@ class basic_json ...@@ -11799,14 +11840,14 @@ class basic_json
} }
JSON_CATCH (std::invalid_argument&) JSON_CATCH (std::invalid_argument&)
{ {
JSON_THROW(parse_error(109, 0, "array index '" + reference_token + "' is not a number")); JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
} }
break; break;
} }
default: default:
{ {
JSON_THROW(out_of_range(404, "unresolved reference token '" + reference_token + "'")); JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
} }
} }
} }
...@@ -11836,7 +11877,7 @@ class basic_json ...@@ -11836,7 +11877,7 @@ class basic_json
// check if nonempty reference string begins with slash // check if nonempty reference string begins with slash
if (reference_string[0] != '/') if (reference_string[0] != '/')
{ {
JSON_THROW(parse_error(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'")); JSON_THROW(parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'"));
} }
// extract the reference tokens: // extract the reference tokens:
...@@ -11871,7 +11912,7 @@ class basic_json ...@@ -11871,7 +11912,7 @@ class basic_json
(reference_token[pos + 1] != '0' and (reference_token[pos + 1] != '0' and
reference_token[pos + 1] != '1')) reference_token[pos + 1] != '1'))
{ {
JSON_THROW(parse_error(108, 0, "escape character '~' must be followed with '0' or '1'")); JSON_THROW(parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
} }
} }
...@@ -12002,7 +12043,7 @@ class basic_json ...@@ -12002,7 +12043,7 @@ class basic_json
{ {
if (not value.is_object()) if (not value.is_object())
{ {
JSON_THROW(type_error(314, "only objects can be unflattened")); JSON_THROW(type_error::create(314, "only objects can be unflattened"));
} }
basic_json result; basic_json result;
...@@ -12012,7 +12053,7 @@ class basic_json ...@@ -12012,7 +12053,7 @@ class basic_json
{ {
if (not element.second.is_primitive()) if (not element.second.is_primitive())
{ {
JSON_THROW(type_error(315, "values in object must be primitive")); JSON_THROW(type_error::create(315, "values in object must be primitive"));
} }
// assign value to reference pointed to by JSON pointer; Note // assign value to reference pointed to by JSON pointer; Note
...@@ -12397,7 +12438,7 @@ class basic_json ...@@ -12397,7 +12438,7 @@ class basic_json
if (static_cast<size_type>(idx) > parent.size()) if (static_cast<size_type>(idx) > parent.size())
{ {
// avoid undefined behavior // avoid undefined behavior
JSON_THROW(out_of_range(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"));
} }
else else
{ {
...@@ -12435,7 +12476,7 @@ class basic_json ...@@ -12435,7 +12476,7 @@ class basic_json
} }
else else
{ {
JSON_THROW(out_of_range(403, "key '" + last_path + "' not found")); JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
} }
} }
else if (parent.is_array()) else if (parent.is_array())
...@@ -12448,7 +12489,7 @@ class basic_json ...@@ -12448,7 +12489,7 @@ class basic_json
// type check: top level value must be an array // type check: top level value must be an array
if (not json_patch.is_array()) if (not json_patch.is_array())
{ {
JSON_THROW(parse_error(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"));
} }
// iterate and apply the operations // iterate and apply the operations
...@@ -12468,13 +12509,13 @@ class basic_json ...@@ -12468,13 +12509,13 @@ class basic_json
// check if desired value is present // check if desired value is present
if (it == val.m_value.object->end()) if (it == val.m_value.object->end())
{ {
JSON_THROW(parse_error(105, 0, error_msg + " must have member '" + member + "'")); JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
} }
// check if result is of type string // check if result is of type string
if (string_type and not it->second.is_string()) if (string_type and not it->second.is_string())
{ {
JSON_THROW(parse_error(105, 0, error_msg + " must have string member '" + member + "'")); JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
} }
// no error: return value // no error: return value
...@@ -12484,7 +12525,7 @@ class basic_json ...@@ -12484,7 +12525,7 @@ class basic_json
// type check: every element of the array must be an object // type check: every element of the array must be an object
if (not val.is_object()) if (not val.is_object())
{ {
JSON_THROW(parse_error(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"));
} }
// collect mandatory members // collect mandatory members
...@@ -12557,7 +12598,7 @@ class basic_json ...@@ -12557,7 +12598,7 @@ class basic_json
// throw an exception if test fails // throw an exception if test fails
if (not success) if (not success)
{ {
JSON_THROW(other_error(501, "unsuccessful: " + val.dump())); JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
} }
break; break;
...@@ -12567,7 +12608,7 @@ class basic_json ...@@ -12567,7 +12608,7 @@ class basic_json
{ {
// op must be "add", "remove", "replace", "move", "copy", or // op must be "add", "remove", "replace", "move", "copy", or
// "test" // "test"
JSON_THROW(parse_error(105, 0, "operation value '" + op + "' is invalid")); JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
} }
} }
} }
......
...@@ -57,3 +57,11 @@ static_assert(noexcept(json(pod{})), ""); ...@@ -57,3 +57,11 @@ static_assert(noexcept(json(pod{})), "");
static_assert(noexcept(j.get<pod>()), ""); static_assert(noexcept(j.get<pod>()), "");
static_assert(not noexcept(j.get<pod_bis>()), ""); static_assert(not noexcept(j.get<pod_bis>()), "");
static_assert(noexcept(json(pod{})), ""); static_assert(noexcept(json(pod{})), "");
// for ERR60-CPP (https://github.com/nlohmann/json/issues/531)
static_assert(std::is_nothrow_copy_constructible<json::exception>::value, "json::exception must be nothrow copy constructible");
static_assert(std::is_nothrow_copy_constructible<json::parse_error>::value, "json::parse_error must be nothrow copy constructible");
static_assert(std::is_nothrow_copy_constructible<json::invalid_iterator>::value, "json::invalid_iterator must be nothrow copy constructible");
static_assert(std::is_nothrow_copy_constructible<json::type_error>::value, "json::type_error must be nothrow copy constructible");
static_assert(std::is_nothrow_copy_constructible<json::out_of_range>::value, "json::out_of_range must be nothrow copy constructible");
static_assert(std::is_nothrow_copy_constructible<json::other_error>::value, "json::other_error must be nothrow copy constructible");
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