option to switch off exceptions

This commit is contained in:
Niels Lohmann 2017-01-16 22:11:07 +01:00
parent 74cbd30cd0
commit 1ab26ab367
6 changed files with 335 additions and 261 deletions

View file

@ -71,6 +71,21 @@ matrix:
after_success: after_success:
- make cppcheck - make cppcheck
# no exceptions
- os: linux
compiler: gcc
env:
- COMPILER=g++-4.9
- SPECIAL=no_exceptions
- TEST_PATTERN="-e \"*\""
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: [g++-4.9, cppcheck]
before_script:
- make FLAGS="-fno-exceptions"
# Coveralls (http://gronlier.fr/blog/2015/01/adding-code-coverage-to-your-c-project/) # Coveralls (http://gronlier.fr/blog/2015/01/adding-code-coverage-to-your-c-project/)
- os: linux - os: linux

View file

@ -88,6 +88,17 @@ SOFTWARE.
#define JSON_DEPRECATED #define JSON_DEPRECATED
#endif #endif
// allow to disable exceptions
#if defined(JSON_NOEXCEPTION) || defined(__EXCEPTIONS)
#define JSON_THROW(exception) std::abort()
#define JSON_TRY if(true)
#define JSON_CATCH(exception) if(false)
#else
#define JSON_THROW(exception) throw exception
#define JSON_TRY try
#define JSON_CATCH(exception) catch(exception)
#endif
/*! /*!
@brief namespace for Niels Lohmann @brief namespace for Niels Lohmann
@see https://github.com/nlohmann @see https://github.com/nlohmann
@ -945,7 +956,7 @@ class basic_json
{ {
if (t == value_t::null) if (t == value_t::null)
{ {
throw std::domain_error("961c151d2e87f2686a955a9be24d316f1362bf21 2.0.10"); // LCOV_EXCL_LINE JSON_THROW(std::domain_error("961c151d2e87f2686a955a9be24d316f1362bf21 2.0.10")); // LCOV_EXCL_LINE
} }
break; break;
} }
@ -1717,7 +1728,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)
{ {
throw std::domain_error("cannot create object from initializer list"); JSON_THROW(std::domain_error("cannot create object from initializer list"));
} }
} }
@ -1895,7 +1906,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)
{ {
throw std::domain_error("iterators are not compatible"); JSON_THROW(std::domain_error("iterators are not compatible"));
} }
// copy type from first iterator // copy type from first iterator
@ -1912,7 +1923,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())
{ {
throw std::out_of_range("iterators out of range"); JSON_THROW(std::out_of_range("iterators out of range"));
} }
break; break;
} }
@ -1971,7 +1982,7 @@ class basic_json
default: default:
{ {
throw std::domain_error("cannot use construct with iterators from " + first.m_object->type_name()); JSON_THROW(std::domain_error("cannot use construct with iterators from " + first.m_object->type_name()));
} }
} }
@ -2655,7 +2666,7 @@ class basic_json
return T(m_value.object->begin(), m_value.object->end()); return T(m_value.object->begin(), m_value.object->end());
} }
throw std::domain_error("type must be object, but is " + type_name()); JSON_THROW(std::domain_error("type must be object, but is " + type_name()));
} }
/// get an object (explicit) /// get an object (explicit)
@ -2666,7 +2677,7 @@ class basic_json
return *(m_value.object); return *(m_value.object);
} }
throw std::domain_error("type must be object, but is " + type_name()); JSON_THROW(std::domain_error("type must be object, but is " + type_name()));
} }
/// get an array (explicit) /// get an array (explicit)
@ -2689,7 +2700,7 @@ class basic_json
return to_vector; return to_vector;
} }
throw std::domain_error("type must be array, but is " + type_name()); JSON_THROW(std::domain_error("type must be array, but is " + type_name()));
} }
/// get an array (explicit) /// get an array (explicit)
@ -2710,7 +2721,7 @@ class basic_json
return to_vector; return to_vector;
} }
throw std::domain_error("type must be array, but is " + type_name()); JSON_THROW(std::domain_error("type must be array, but is " + type_name()));
} }
/// get an array (explicit) /// get an array (explicit)
@ -2724,7 +2735,7 @@ class basic_json
return T(m_value.array->begin(), m_value.array->end()); return T(m_value.array->begin(), m_value.array->end());
} }
throw std::domain_error("type must be array, but is " + type_name()); JSON_THROW(std::domain_error("type must be array, but is " + type_name()));
} }
/// get an array (explicit) /// get an array (explicit)
@ -2735,7 +2746,7 @@ class basic_json
return *(m_value.array); return *(m_value.array);
} }
throw std::domain_error("type must be array, but is " + type_name()); JSON_THROW(std::domain_error("type must be array, but is " + type_name()));
} }
/// get a string (explicit) /// get a string (explicit)
@ -2748,7 +2759,7 @@ class basic_json
return *m_value.string; return *m_value.string;
} }
throw std::domain_error("type must be string, but is " + type_name()); JSON_THROW(std::domain_error("type must be string, but is " + type_name()));
} }
/// get a number (explicit) /// get a number (explicit)
@ -2775,17 +2786,22 @@ class basic_json
default: default:
{ {
throw std::domain_error("type must be number, but is " + type_name()); JSON_THROW(std::domain_error("type must be number, but is " + type_name()));
} }
} }
} }
/// get a boolean (explicit) /// get a boolean (explicit)
constexpr boolean_t get_impl(boolean_t* /*unused*/) const boolean_t get_impl(boolean_t* /*unused*/) const
{ {
return is_boolean() if (is_boolean())
? m_value.boolean {
: throw std::domain_error("type must be boolean, but is " + type_name()); return m_value.boolean;
}
else
{
JSON_THROW(std::domain_error("type must be boolean, but is " + type_name()));
}
} }
/// get a pointer to the value (object) /// get a pointer to the value (object)
@ -3197,19 +3213,19 @@ class basic_json
// at only works for arrays // at only works for arrays
if (is_array()) if (is_array())
{ {
try JSON_TRY
{ {
return m_value.array->at(idx); return m_value.array->at(idx);
} }
catch (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
throw std::out_of_range("array index " + std::to_string(idx) + " is out of range"); JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
} }
} }
else else
{ {
throw std::domain_error("cannot use at() with " + type_name()); JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
} }
} }
@ -3240,19 +3256,19 @@ class basic_json
// at only works for arrays // at only works for arrays
if (is_array()) if (is_array())
{ {
try JSON_TRY
{ {
return m_value.array->at(idx); return m_value.array->at(idx);
} }
catch (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
throw std::out_of_range("array index " + std::to_string(idx) + " is out of range"); JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
} }
} }
else else
{ {
throw std::domain_error("cannot use at() with " + type_name()); JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
} }
} }
@ -3287,19 +3303,19 @@ class basic_json
// at only works for objects // at only works for objects
if (is_object()) if (is_object())
{ {
try JSON_TRY
{ {
return m_value.object->at(key); return m_value.object->at(key);
} }
catch (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
throw std::out_of_range("key '" + key + "' not found"); JSON_THROW(std::out_of_range("key '" + key + "' not found"));
} }
} }
else else
{ {
throw std::domain_error("cannot use at() with " + type_name()); JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
} }
} }
@ -3334,19 +3350,19 @@ class basic_json
// at only works for objects // at only works for objects
if (is_object()) if (is_object())
{ {
try JSON_TRY
{ {
return m_value.object->at(key); return m_value.object->at(key);
} }
catch (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
throw std::out_of_range("key '" + key + "' not found"); JSON_THROW(std::out_of_range("key '" + key + "' not found"));
} }
} }
else else
{ {
throw std::domain_error("cannot use at() with " + type_name()); JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
} }
} }
@ -3399,7 +3415,7 @@ class basic_json
return m_value.array->operator[](idx); return m_value.array->operator[](idx);
} }
throw std::domain_error("cannot use operator[] with " + type_name()); JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
} }
/*! /*!
@ -3429,7 +3445,7 @@ class basic_json
return m_value.array->operator[](idx); return m_value.array->operator[](idx);
} }
throw std::domain_error("cannot use operator[] with " + type_name()); JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
} }
/*! /*!
@ -3475,7 +3491,7 @@ class basic_json
return m_value.object->operator[](key); return m_value.object->operator[](key);
} }
throw std::domain_error("cannot use operator[] with " + type_name()); JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
} }
/*! /*!
@ -3517,7 +3533,7 @@ class basic_json
return m_value.object->find(key)->second; return m_value.object->find(key)->second;
} }
throw std::domain_error("cannot use operator[] with " + type_name()); JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
} }
/*! /*!
@ -3632,7 +3648,7 @@ class basic_json
return m_value.object->operator[](key); return m_value.object->operator[](key);
} }
throw std::domain_error("cannot use operator[] with " + type_name()); JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
} }
/*! /*!
@ -3675,7 +3691,7 @@ class basic_json
return m_value.object->find(key)->second; return m_value.object->find(key)->second;
} }
throw std::domain_error("cannot use operator[] with " + type_name()); JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
} }
/*! /*!
@ -3744,7 +3760,7 @@ class basic_json
} }
else else
{ {
throw std::domain_error("cannot use value() with " + type_name()); JSON_THROW(std::domain_error("cannot use value() with " + type_name()));
} }
} }
@ -3806,17 +3822,17 @@ class basic_json
if (is_object()) if (is_object())
{ {
// if pointer resolves a value, return it or use default value // if pointer resolves a value, return it or use default value
try JSON_TRY
{ {
return ptr.get_checked(this); return ptr.get_checked(this);
} }
catch (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
return default_value; return default_value;
} }
} }
throw std::domain_error("cannot use value() with " + type_name()); JSON_THROW(std::domain_error("cannot use value() with " + type_name()));
} }
/*! /*!
@ -3967,7 +3983,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)
{ {
throw std::domain_error("iterator does not fit current value"); JSON_THROW(std::domain_error("iterator does not fit current value"));
} }
IteratorType result = end(); IteratorType result = end();
@ -3982,7 +3998,7 @@ class basic_json
{ {
if (not pos.m_it.primitive_iterator.is_begin()) if (not pos.m_it.primitive_iterator.is_begin())
{ {
throw std::out_of_range("iterator out of range"); JSON_THROW(std::out_of_range("iterator out of range"));
} }
if (is_string()) if (is_string())
@ -4012,7 +4028,7 @@ class basic_json
default: default:
{ {
throw std::domain_error("cannot use erase() with " + type_name()); JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
} }
} }
@ -4074,7 +4090,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)
{ {
throw std::domain_error("iterators do not fit current value"); JSON_THROW(std::domain_error("iterators do not fit current value"));
} }
IteratorType result = end(); IteratorType result = end();
@ -4089,7 +4105,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())
{ {
throw std::out_of_range("iterators out of range"); JSON_THROW(std::out_of_range("iterators out of range"));
} }
if (is_string()) if (is_string())
@ -4121,7 +4137,7 @@ class basic_json
default: default:
{ {
throw std::domain_error("cannot use erase() with " + type_name()); JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
} }
} }
@ -4165,7 +4181,7 @@ class basic_json
return m_value.object->erase(key); return m_value.object->erase(key);
} }
throw std::domain_error("cannot use erase() with " + type_name()); JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
} }
/*! /*!
@ -4199,14 +4215,14 @@ class basic_json
{ {
if (idx >= size()) if (idx >= size())
{ {
throw std::out_of_range("array index " + std::to_string(idx) + " is out of range"); JSON_THROW(std::out_of_range("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
{ {
throw std::domain_error("cannot use erase() with " + type_name()); JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
} }
} }
@ -4924,7 +4940,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()))
{ {
throw std::domain_error("cannot use push_back() with " + type_name()); JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
} }
// transform null object into an array // transform null object into an array
@ -4960,7 +4976,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()))
{ {
throw std::domain_error("cannot use push_back() with " + type_name()); JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
} }
// transform null object into an array // transform null object into an array
@ -5010,7 +5026,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()))
{ {
throw std::domain_error("cannot use push_back() with " + type_name()); JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
} }
// transform null object into an object // transform null object into an object
@ -5110,7 +5126,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()))
{ {
throw std::domain_error("cannot use emplace_back() with " + type_name()); JSON_THROW(std::domain_error("cannot use emplace_back() with " + type_name()));
} }
// transform null object into an array // transform null object into an array
@ -5158,7 +5174,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()))
{ {
throw std::domain_error("cannot use emplace() with " + type_name()); JSON_THROW(std::domain_error("cannot use emplace() with " + type_name()));
} }
// transform null object into an object // transform null object into an object
@ -5209,7 +5225,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)
{ {
throw std::domain_error("iterator does not fit current value"); JSON_THROW(std::domain_error("iterator does not fit current value"));
} }
// insert to array and return iterator // insert to array and return iterator
@ -5218,7 +5234,7 @@ class basic_json
return result; return result;
} }
throw std::domain_error("cannot use insert() with " + type_name()); JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
} }
/*! /*!
@ -5262,7 +5278,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)
{ {
throw std::domain_error("iterator does not fit current value"); JSON_THROW(std::domain_error("iterator does not fit current value"));
} }
// insert to array and return iterator // insert to array and return iterator
@ -5271,7 +5287,7 @@ class basic_json
return result; return result;
} }
throw std::domain_error("cannot use insert() with " + type_name()); JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
} }
/*! /*!
@ -5309,24 +5325,24 @@ class basic_json
// insert only works for arrays // insert only works for arrays
if (not is_array()) if (not is_array())
{ {
throw std::domain_error("cannot use insert() with " + type_name()); JSON_THROW(std::domain_error("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)
{ {
throw std::domain_error("iterator does not fit current value"); JSON_THROW(std::domain_error("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)
{ {
throw std::domain_error("iterators do not fit"); JSON_THROW(std::domain_error("iterators do not fit"));
} }
if (first.m_object == this or last.m_object == this) if (first.m_object == this or last.m_object == this)
{ {
throw std::domain_error("passed iterators may not belong to container"); JSON_THROW(std::domain_error("passed iterators may not belong to container"));
} }
// insert to array and return iterator // insert to array and return iterator
@ -5367,13 +5383,13 @@ class basic_json
// insert only works for arrays // insert only works for arrays
if (not is_array()) if (not is_array())
{ {
throw std::domain_error("cannot use insert() with " + type_name()); JSON_THROW(std::domain_error("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)
{ {
throw std::domain_error("iterator does not fit current value"); JSON_THROW(std::domain_error("iterator does not fit current value"));
} }
// insert to array and return iterator // insert to array and return iterator
@ -5440,7 +5456,7 @@ class basic_json
} }
else else
{ {
throw std::domain_error("cannot use swap() with " + type_name()); JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
} }
} }
@ -5473,7 +5489,7 @@ class basic_json
} }
else else
{ {
throw std::domain_error("cannot use swap() with " + type_name()); JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
} }
} }
@ -5506,7 +5522,7 @@ class basic_json
} }
else else
{ {
throw std::domain_error("cannot use swap() with " + type_name()); JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
} }
} }
@ -6350,7 +6366,7 @@ class basic_json
{ {
if (current_index + sizeof(T) + 1 > vec.size()) if (current_index + sizeof(T) + 1 > vec.size())
{ {
throw std::out_of_range("cannot read " + std::to_string(sizeof(T)) + " bytes from vector"); JSON_THROW(std::out_of_range("cannot read " + std::to_string(sizeof(T)) + " bytes from vector"));
} }
T result; T result;
@ -6900,19 +6916,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)
{ {
throw std::out_of_range("len out of range"); JSON_THROW(std::out_of_range("len out of range"));
} }
// 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)))
{ {
throw std::out_of_range("len+offset out of range"); JSON_THROW(std::out_of_range("len+offset out of range"));
} }
// 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)
{ {
throw std::out_of_range("len+offset out of range"); JSON_THROW(std::out_of_range("len+offset out of range"));
} }
} }
@ -7148,7 +7164,7 @@ class basic_json
default: default:
{ {
throw std::invalid_argument("error parsing a msgpack @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))); JSON_THROW(std::invalid_argument("error parsing a msgpack @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))));
} }
} }
} }
@ -7631,7 +7647,7 @@ class basic_json
default: // anything else (0xFF is handled inside the other types) default: // anything else (0xFF is handled inside the other types)
{ {
throw std::invalid_argument("error parsing a CBOR @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))); JSON_THROW(std::invalid_argument("error parsing a CBOR @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))));
} }
} }
} }
@ -8521,7 +8537,7 @@ class basic_json
case basic_json::value_t::null: case basic_json::value_t::null:
{ {
throw std::out_of_range("cannot get value"); JSON_THROW(std::out_of_range("cannot get value"));
} }
default: default:
@ -8531,7 +8547,7 @@ class basic_json
return *m_object; return *m_object;
} }
throw std::out_of_range("cannot get value"); JSON_THROW(std::out_of_range("cannot get value"));
} }
} }
} }
@ -8565,7 +8581,7 @@ class basic_json
return m_object; return m_object;
} }
throw std::out_of_range("cannot get value"); JSON_THROW(std::out_of_range("cannot get value"));
} }
} }
} }
@ -8665,7 +8681,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)
{ {
throw std::domain_error("cannot compare iterators of different containers"); JSON_THROW(std::domain_error("cannot compare iterators of different containers"));
} }
assert(m_object != nullptr); assert(m_object != nullptr);
@ -8707,7 +8723,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)
{ {
throw std::domain_error("cannot compare iterators of different containers"); JSON_THROW(std::domain_error("cannot compare iterators of different containers"));
} }
assert(m_object != nullptr); assert(m_object != nullptr);
@ -8716,7 +8732,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
throw std::domain_error("cannot compare order of object iterators"); JSON_THROW(std::domain_error("cannot compare order of object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
@ -8770,7 +8786,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
throw std::domain_error("cannot use offsets with object iterators"); JSON_THROW(std::domain_error("cannot use offsets with object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
@ -8832,7 +8848,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
throw std::domain_error("cannot use offsets with object iterators"); JSON_THROW(std::domain_error("cannot use offsets with object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
@ -8859,7 +8875,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
throw std::domain_error("cannot use operator[] for object iterators"); JSON_THROW(std::domain_error("cannot use operator[] for object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
@ -8869,7 +8885,7 @@ class basic_json
case basic_json::value_t::null: case basic_json::value_t::null:
{ {
throw std::out_of_range("cannot get value"); JSON_THROW(std::out_of_range("cannot get value"));
} }
default: default:
@ -8879,7 +8895,7 @@ class basic_json
return *m_object; return *m_object;
} }
throw std::out_of_range("cannot get value"); JSON_THROW(std::out_of_range("cannot get value"));
} }
} }
} }
@ -8897,7 +8913,7 @@ class basic_json
return m_it.object_iterator->first; return m_it.object_iterator->first;
} }
throw std::domain_error("cannot use key() for non-object iterators"); JSON_THROW(std::domain_error("cannot use key() for non-object iterators"));
} }
/*! /*!
@ -9082,7 +9098,7 @@ class basic_json
// immediately abort if stream is erroneous // immediately abort if stream is erroneous
if (s.fail()) if (s.fail())
{ {
throw std::invalid_argument("stream error"); JSON_THROW(std::invalid_argument("stream error"));
} }
// fill buffer // fill buffer
@ -9149,7 +9165,7 @@ class basic_json
} }
else else
{ {
throw std::invalid_argument("missing or wrong low surrogate"); JSON_THROW(std::invalid_argument("missing or wrong low surrogate"));
} }
} }
@ -9183,7 +9199,7 @@ class basic_json
} }
else else
{ {
throw std::out_of_range("code points above 0x10FFFF are invalid"); JSON_THROW(std::out_of_range("code points above 0x10FFFF are invalid"));
} }
return result; return result;
@ -10415,7 +10431,7 @@ basic_json_parser_66:
// 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')
{ {
throw std::invalid_argument("missing low surrogate"); JSON_THROW(std::invalid_argument("missing low surrogate"));
} }
// get code yyyy from uxxxx\uyyyy // get code yyyy from uxxxx\uyyyy
@ -10428,7 +10444,7 @@ basic_json_parser_66:
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
throw std::invalid_argument("missing high surrogate"); JSON_THROW(std::invalid_argument("missing high surrogate"));
} }
else else
{ {
@ -10906,7 +10922,7 @@ basic_json_parser_66:
"'") : "'") :
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);
throw std::invalid_argument(error_msg); JSON_THROW(std::invalid_argument(error_msg));
} }
} }
@ -10918,7 +10934,7 @@ basic_json_parser_66:
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));
throw std::invalid_argument(error_msg); JSON_THROW(std::invalid_argument(error_msg));
} }
} }
@ -11014,7 +11030,7 @@ basic_json_parser_66:
{ {
if (is_root()) if (is_root())
{ {
throw std::domain_error("JSON pointer has no parent"); JSON_THROW(std::domain_error("JSON pointer has no parent"));
} }
auto last = reference_tokens.back(); auto last = reference_tokens.back();
@ -11032,7 +11048,7 @@ basic_json_parser_66:
{ {
if (is_root()) if (is_root())
{ {
throw std::domain_error("JSON pointer has no parent"); JSON_THROW(std::domain_error("JSON pointer has no parent"));
} }
json_pointer result = *this; json_pointer result = *this;
@ -11093,7 +11109,7 @@ basic_json_parser_66:
*/ */
default: default:
{ {
throw std::domain_error("invalid value to unflatten"); JSON_THROW(std::domain_error("invalid value to unflatten"));
} }
} }
} }
@ -11161,7 +11177,7 @@ basic_json_parser_66:
// 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')
{ {
throw std::domain_error("array index must not begin with '0'"); JSON_THROW(std::domain_error("array index must not begin with '0'"));
} }
if (reference_token == "-") if (reference_token == "-")
@ -11179,7 +11195,7 @@ basic_json_parser_66:
default: default:
{ {
throw std::out_of_range("unresolved reference token '" + reference_token + "'"); JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
} }
} }
} }
@ -11213,7 +11229,7 @@ basic_json_parser_66:
// 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')
{ {
throw std::domain_error("array index must not begin with '0'"); JSON_THROW(std::domain_error("array index must not begin with '0'"));
} }
// note: at performs range check // note: at performs range check
@ -11223,7 +11239,7 @@ basic_json_parser_66:
default: default:
{ {
throw std::out_of_range("unresolved reference token '" + reference_token + "'"); JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
} }
} }
} }
@ -11265,7 +11281,7 @@ basic_json_parser_66:
// 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')
{ {
throw std::domain_error("array index must not begin with '0'"); JSON_THROW(std::domain_error("array index must not begin with '0'"));
} }
// use unchecked array access // use unchecked array access
@ -11275,7 +11291,7 @@ basic_json_parser_66:
default: default:
{ {
throw std::out_of_range("unresolved reference token '" + reference_token + "'"); JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
} }
} }
} }
@ -11309,7 +11325,7 @@ basic_json_parser_66:
// 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')
{ {
throw std::domain_error("array index must not begin with '0'"); JSON_THROW(std::domain_error("array index must not begin with '0'"));
} }
// note: at performs range check // note: at performs range check
@ -11319,7 +11335,7 @@ basic_json_parser_66:
default: default:
{ {
throw std::out_of_range("unresolved reference token '" + reference_token + "'"); JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
} }
} }
} }
@ -11341,7 +11357,7 @@ basic_json_parser_66:
// check if nonempty reference string begins with slash // check if nonempty reference string begins with slash
if (reference_string[0] != '/') if (reference_string[0] != '/')
{ {
throw std::domain_error("JSON pointer must be empty or begin with '/'"); JSON_THROW(std::domain_error("JSON pointer must be empty or begin with '/'"));
} }
// extract the reference tokens: // extract the reference tokens:
@ -11376,7 +11392,7 @@ basic_json_parser_66:
(reference_token[pos + 1] != '0' and (reference_token[pos + 1] != '0' and
reference_token[pos + 1] != '1')) reference_token[pos + 1] != '1'))
{ {
throw std::domain_error("escape error: '~' must be followed with '0' or '1'"); JSON_THROW(std::domain_error("escape error: '~' must be followed with '0' or '1'"));
} }
} }
@ -11502,7 +11518,7 @@ basic_json_parser_66:
{ {
if (not value.is_object()) if (not value.is_object())
{ {
throw std::domain_error("only objects can be unflattened"); JSON_THROW(std::domain_error("only objects can be unflattened"));
} }
basic_json result; basic_json result;
@ -11512,7 +11528,7 @@ basic_json_parser_66:
{ {
if (not element.second.is_primitive()) if (not element.second.is_primitive())
{ {
throw std::domain_error("values in object must be primitive"); JSON_THROW(std::domain_error("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
@ -11841,7 +11857,7 @@ basic_json_parser_66:
if (static_cast<size_type>(idx) > parent.size()) if (static_cast<size_type>(idx) > parent.size())
{ {
// avoid undefined behavior // avoid undefined behavior
throw std::out_of_range("array index " + std::to_string(idx) + " is out of range"); JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
} }
else else
{ {
@ -11879,7 +11895,7 @@ basic_json_parser_66:
} }
else else
{ {
throw std::out_of_range("key '" + last_path + "' not found"); JSON_THROW(std::out_of_range("key '" + last_path + "' not found"));
} }
} }
else if (parent.is_array()) else if (parent.is_array())
@ -11893,7 +11909,7 @@ basic_json_parser_66:
if (not json_patch.is_array()) if (not json_patch.is_array())
{ {
// a JSON patch must be an array of objects // a JSON patch must be an array of objects
throw std::invalid_argument("JSON patch must be an array of objects"); JSON_THROW(std::invalid_argument("JSON patch must be an array of objects"));
} }
// iterate and apply th eoperations // iterate and apply th eoperations
@ -11913,13 +11929,13 @@ basic_json_parser_66:
// 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())
{ {
throw std::invalid_argument(error_msg + " must have member '" + member + "'"); JSON_THROW(std::invalid_argument(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())
{ {
throw std::invalid_argument(error_msg + " must have string member '" + member + "'"); JSON_THROW(std::invalid_argument(error_msg + " must have string member '" + member + "'"));
} }
// no error: return value // no error: return value
@ -11929,7 +11945,7 @@ basic_json_parser_66:
// type check // type check
if (not val.is_object()) if (not val.is_object())
{ {
throw std::invalid_argument("JSON patch must be an array of objects"); JSON_THROW(std::invalid_argument("JSON patch must be an array of objects"));
} }
// collect mandatory members // collect mandatory members
@ -11988,13 +12004,13 @@ basic_json_parser_66:
case patch_operations::test: case patch_operations::test:
{ {
bool success = false; bool success = false;
try JSON_TRY
{ {
// check if "value" matches the one at "path" // check if "value" matches the one at "path"
// the "path" location must exist - use at() // the "path" location must exist - use at()
success = (result.at(ptr) == get_value("test", "value", false)); success = (result.at(ptr) == get_value("test", "value", false));
} }
catch (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// ignore out of range errors: success remains false // ignore out of range errors: success remains false
} }
@ -12002,7 +12018,7 @@ basic_json_parser_66:
// throw an exception if test fails // throw an exception if test fails
if (not success) if (not success)
{ {
throw std::domain_error("unsuccessful: " + val.dump()); JSON_THROW(std::domain_error("unsuccessful: " + val.dump()));
} }
break; break;
@ -12012,7 +12028,7 @@ basic_json_parser_66:
{ {
// op must be "add", "remove", "replace", "move", "copy", or // op must be "add", "remove", "replace", "move", "copy", or
// "test" // "test"
throw std::invalid_argument("operation value '" + op + "' is invalid"); JSON_THROW(std::invalid_argument("operation value '" + op + "' is invalid"));
} }
} }
} }
@ -12285,4 +12301,10 @@ inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
// clean up
#undef JSON_THROW
#undef JSON_TRY
#undef JSON_CATCH
#undef JSON_DEPRECATED
#endif #endif

View file

@ -88,6 +88,17 @@ SOFTWARE.
#define JSON_DEPRECATED #define JSON_DEPRECATED
#endif #endif
// allow to disable exceptions
#if defined(JSON_NOEXCEPTION) || defined(__EXCEPTIONS)
#define JSON_THROW(exception) std::abort()
#define JSON_TRY if(true)
#define JSON_CATCH(exception) if(false)
#else
#define JSON_THROW(exception) throw exception
#define JSON_TRY try
#define JSON_CATCH(exception) catch(exception)
#endif
/*! /*!
@brief namespace for Niels Lohmann @brief namespace for Niels Lohmann
@see https://github.com/nlohmann @see https://github.com/nlohmann
@ -945,7 +956,7 @@ class basic_json
{ {
if (t == value_t::null) if (t == value_t::null)
{ {
throw std::domain_error("961c151d2e87f2686a955a9be24d316f1362bf21 2.0.10"); // LCOV_EXCL_LINE JSON_THROW(std::domain_error("961c151d2e87f2686a955a9be24d316f1362bf21 2.0.10")); // LCOV_EXCL_LINE
} }
break; break;
} }
@ -1717,7 +1728,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)
{ {
throw std::domain_error("cannot create object from initializer list"); JSON_THROW(std::domain_error("cannot create object from initializer list"));
} }
} }
@ -1895,7 +1906,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)
{ {
throw std::domain_error("iterators are not compatible"); JSON_THROW(std::domain_error("iterators are not compatible"));
} }
// copy type from first iterator // copy type from first iterator
@ -1912,7 +1923,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())
{ {
throw std::out_of_range("iterators out of range"); JSON_THROW(std::out_of_range("iterators out of range"));
} }
break; break;
} }
@ -1971,7 +1982,7 @@ class basic_json
default: default:
{ {
throw std::domain_error("cannot use construct with iterators from " + first.m_object->type_name()); JSON_THROW(std::domain_error("cannot use construct with iterators from " + first.m_object->type_name()));
} }
} }
@ -2655,7 +2666,7 @@ class basic_json
return T(m_value.object->begin(), m_value.object->end()); return T(m_value.object->begin(), m_value.object->end());
} }
throw std::domain_error("type must be object, but is " + type_name()); JSON_THROW(std::domain_error("type must be object, but is " + type_name()));
} }
/// get an object (explicit) /// get an object (explicit)
@ -2666,7 +2677,7 @@ class basic_json
return *(m_value.object); return *(m_value.object);
} }
throw std::domain_error("type must be object, but is " + type_name()); JSON_THROW(std::domain_error("type must be object, but is " + type_name()));
} }
/// get an array (explicit) /// get an array (explicit)
@ -2689,7 +2700,7 @@ class basic_json
return to_vector; return to_vector;
} }
throw std::domain_error("type must be array, but is " + type_name()); JSON_THROW(std::domain_error("type must be array, but is " + type_name()));
} }
/// get an array (explicit) /// get an array (explicit)
@ -2710,7 +2721,7 @@ class basic_json
return to_vector; return to_vector;
} }
throw std::domain_error("type must be array, but is " + type_name()); JSON_THROW(std::domain_error("type must be array, but is " + type_name()));
} }
/// get an array (explicit) /// get an array (explicit)
@ -2724,7 +2735,7 @@ class basic_json
return T(m_value.array->begin(), m_value.array->end()); return T(m_value.array->begin(), m_value.array->end());
} }
throw std::domain_error("type must be array, but is " + type_name()); JSON_THROW(std::domain_error("type must be array, but is " + type_name()));
} }
/// get an array (explicit) /// get an array (explicit)
@ -2735,7 +2746,7 @@ class basic_json
return *(m_value.array); return *(m_value.array);
} }
throw std::domain_error("type must be array, but is " + type_name()); JSON_THROW(std::domain_error("type must be array, but is " + type_name()));
} }
/// get a string (explicit) /// get a string (explicit)
@ -2748,7 +2759,7 @@ class basic_json
return *m_value.string; return *m_value.string;
} }
throw std::domain_error("type must be string, but is " + type_name()); JSON_THROW(std::domain_error("type must be string, but is " + type_name()));
} }
/// get a number (explicit) /// get a number (explicit)
@ -2775,17 +2786,22 @@ class basic_json
default: default:
{ {
throw std::domain_error("type must be number, but is " + type_name()); JSON_THROW(std::domain_error("type must be number, but is " + type_name()));
} }
} }
} }
/// get a boolean (explicit) /// get a boolean (explicit)
constexpr boolean_t get_impl(boolean_t* /*unused*/) const boolean_t get_impl(boolean_t* /*unused*/) const
{ {
return is_boolean() if (is_boolean())
? m_value.boolean {
: throw std::domain_error("type must be boolean, but is " + type_name()); return m_value.boolean;
}
else
{
JSON_THROW(std::domain_error("type must be boolean, but is " + type_name()));
}
} }
/// get a pointer to the value (object) /// get a pointer to the value (object)
@ -3197,19 +3213,19 @@ class basic_json
// at only works for arrays // at only works for arrays
if (is_array()) if (is_array())
{ {
try JSON_TRY
{ {
return m_value.array->at(idx); return m_value.array->at(idx);
} }
catch (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
throw std::out_of_range("array index " + std::to_string(idx) + " is out of range"); JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
} }
} }
else else
{ {
throw std::domain_error("cannot use at() with " + type_name()); JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
} }
} }
@ -3240,19 +3256,19 @@ class basic_json
// at only works for arrays // at only works for arrays
if (is_array()) if (is_array())
{ {
try JSON_TRY
{ {
return m_value.array->at(idx); return m_value.array->at(idx);
} }
catch (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
throw std::out_of_range("array index " + std::to_string(idx) + " is out of range"); JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
} }
} }
else else
{ {
throw std::domain_error("cannot use at() with " + type_name()); JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
} }
} }
@ -3287,19 +3303,19 @@ class basic_json
// at only works for objects // at only works for objects
if (is_object()) if (is_object())
{ {
try JSON_TRY
{ {
return m_value.object->at(key); return m_value.object->at(key);
} }
catch (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
throw std::out_of_range("key '" + key + "' not found"); JSON_THROW(std::out_of_range("key '" + key + "' not found"));
} }
} }
else else
{ {
throw std::domain_error("cannot use at() with " + type_name()); JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
} }
} }
@ -3334,19 +3350,19 @@ class basic_json
// at only works for objects // at only works for objects
if (is_object()) if (is_object())
{ {
try JSON_TRY
{ {
return m_value.object->at(key); return m_value.object->at(key);
} }
catch (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// create better exception explanation // create better exception explanation
throw std::out_of_range("key '" + key + "' not found"); JSON_THROW(std::out_of_range("key '" + key + "' not found"));
} }
} }
else else
{ {
throw std::domain_error("cannot use at() with " + type_name()); JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
} }
} }
@ -3399,7 +3415,7 @@ class basic_json
return m_value.array->operator[](idx); return m_value.array->operator[](idx);
} }
throw std::domain_error("cannot use operator[] with " + type_name()); JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
} }
/*! /*!
@ -3429,7 +3445,7 @@ class basic_json
return m_value.array->operator[](idx); return m_value.array->operator[](idx);
} }
throw std::domain_error("cannot use operator[] with " + type_name()); JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
} }
/*! /*!
@ -3475,7 +3491,7 @@ class basic_json
return m_value.object->operator[](key); return m_value.object->operator[](key);
} }
throw std::domain_error("cannot use operator[] with " + type_name()); JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
} }
/*! /*!
@ -3517,7 +3533,7 @@ class basic_json
return m_value.object->find(key)->second; return m_value.object->find(key)->second;
} }
throw std::domain_error("cannot use operator[] with " + type_name()); JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
} }
/*! /*!
@ -3632,7 +3648,7 @@ class basic_json
return m_value.object->operator[](key); return m_value.object->operator[](key);
} }
throw std::domain_error("cannot use operator[] with " + type_name()); JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
} }
/*! /*!
@ -3675,7 +3691,7 @@ class basic_json
return m_value.object->find(key)->second; return m_value.object->find(key)->second;
} }
throw std::domain_error("cannot use operator[] with " + type_name()); JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
} }
/*! /*!
@ -3744,7 +3760,7 @@ class basic_json
} }
else else
{ {
throw std::domain_error("cannot use value() with " + type_name()); JSON_THROW(std::domain_error("cannot use value() with " + type_name()));
} }
} }
@ -3806,17 +3822,17 @@ class basic_json
if (is_object()) if (is_object())
{ {
// if pointer resolves a value, return it or use default value // if pointer resolves a value, return it or use default value
try JSON_TRY
{ {
return ptr.get_checked(this); return ptr.get_checked(this);
} }
catch (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
return default_value; return default_value;
} }
} }
throw std::domain_error("cannot use value() with " + type_name()); JSON_THROW(std::domain_error("cannot use value() with " + type_name()));
} }
/*! /*!
@ -3967,7 +3983,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)
{ {
throw std::domain_error("iterator does not fit current value"); JSON_THROW(std::domain_error("iterator does not fit current value"));
} }
IteratorType result = end(); IteratorType result = end();
@ -3982,7 +3998,7 @@ class basic_json
{ {
if (not pos.m_it.primitive_iterator.is_begin()) if (not pos.m_it.primitive_iterator.is_begin())
{ {
throw std::out_of_range("iterator out of range"); JSON_THROW(std::out_of_range("iterator out of range"));
} }
if (is_string()) if (is_string())
@ -4012,7 +4028,7 @@ class basic_json
default: default:
{ {
throw std::domain_error("cannot use erase() with " + type_name()); JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
} }
} }
@ -4074,7 +4090,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)
{ {
throw std::domain_error("iterators do not fit current value"); JSON_THROW(std::domain_error("iterators do not fit current value"));
} }
IteratorType result = end(); IteratorType result = end();
@ -4089,7 +4105,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())
{ {
throw std::out_of_range("iterators out of range"); JSON_THROW(std::out_of_range("iterators out of range"));
} }
if (is_string()) if (is_string())
@ -4121,7 +4137,7 @@ class basic_json
default: default:
{ {
throw std::domain_error("cannot use erase() with " + type_name()); JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
} }
} }
@ -4165,7 +4181,7 @@ class basic_json
return m_value.object->erase(key); return m_value.object->erase(key);
} }
throw std::domain_error("cannot use erase() with " + type_name()); JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
} }
/*! /*!
@ -4199,14 +4215,14 @@ class basic_json
{ {
if (idx >= size()) if (idx >= size())
{ {
throw std::out_of_range("array index " + std::to_string(idx) + " is out of range"); JSON_THROW(std::out_of_range("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
{ {
throw std::domain_error("cannot use erase() with " + type_name()); JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
} }
} }
@ -4924,7 +4940,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()))
{ {
throw std::domain_error("cannot use push_back() with " + type_name()); JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
} }
// transform null object into an array // transform null object into an array
@ -4960,7 +4976,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()))
{ {
throw std::domain_error("cannot use push_back() with " + type_name()); JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
} }
// transform null object into an array // transform null object into an array
@ -5010,7 +5026,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()))
{ {
throw std::domain_error("cannot use push_back() with " + type_name()); JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
} }
// transform null object into an object // transform null object into an object
@ -5110,7 +5126,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()))
{ {
throw std::domain_error("cannot use emplace_back() with " + type_name()); JSON_THROW(std::domain_error("cannot use emplace_back() with " + type_name()));
} }
// transform null object into an array // transform null object into an array
@ -5158,7 +5174,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()))
{ {
throw std::domain_error("cannot use emplace() with " + type_name()); JSON_THROW(std::domain_error("cannot use emplace() with " + type_name()));
} }
// transform null object into an object // transform null object into an object
@ -5209,7 +5225,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)
{ {
throw std::domain_error("iterator does not fit current value"); JSON_THROW(std::domain_error("iterator does not fit current value"));
} }
// insert to array and return iterator // insert to array and return iterator
@ -5218,7 +5234,7 @@ class basic_json
return result; return result;
} }
throw std::domain_error("cannot use insert() with " + type_name()); JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
} }
/*! /*!
@ -5262,7 +5278,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)
{ {
throw std::domain_error("iterator does not fit current value"); JSON_THROW(std::domain_error("iterator does not fit current value"));
} }
// insert to array and return iterator // insert to array and return iterator
@ -5271,7 +5287,7 @@ class basic_json
return result; return result;
} }
throw std::domain_error("cannot use insert() with " + type_name()); JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
} }
/*! /*!
@ -5309,24 +5325,24 @@ class basic_json
// insert only works for arrays // insert only works for arrays
if (not is_array()) if (not is_array())
{ {
throw std::domain_error("cannot use insert() with " + type_name()); JSON_THROW(std::domain_error("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)
{ {
throw std::domain_error("iterator does not fit current value"); JSON_THROW(std::domain_error("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)
{ {
throw std::domain_error("iterators do not fit"); JSON_THROW(std::domain_error("iterators do not fit"));
} }
if (first.m_object == this or last.m_object == this) if (first.m_object == this or last.m_object == this)
{ {
throw std::domain_error("passed iterators may not belong to container"); JSON_THROW(std::domain_error("passed iterators may not belong to container"));
} }
// insert to array and return iterator // insert to array and return iterator
@ -5367,13 +5383,13 @@ class basic_json
// insert only works for arrays // insert only works for arrays
if (not is_array()) if (not is_array())
{ {
throw std::domain_error("cannot use insert() with " + type_name()); JSON_THROW(std::domain_error("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)
{ {
throw std::domain_error("iterator does not fit current value"); JSON_THROW(std::domain_error("iterator does not fit current value"));
} }
// insert to array and return iterator // insert to array and return iterator
@ -5440,7 +5456,7 @@ class basic_json
} }
else else
{ {
throw std::domain_error("cannot use swap() with " + type_name()); JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
} }
} }
@ -5473,7 +5489,7 @@ class basic_json
} }
else else
{ {
throw std::domain_error("cannot use swap() with " + type_name()); JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
} }
} }
@ -5506,7 +5522,7 @@ class basic_json
} }
else else
{ {
throw std::domain_error("cannot use swap() with " + type_name()); JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
} }
} }
@ -6350,7 +6366,7 @@ class basic_json
{ {
if (current_index + sizeof(T) + 1 > vec.size()) if (current_index + sizeof(T) + 1 > vec.size())
{ {
throw std::out_of_range("cannot read " + std::to_string(sizeof(T)) + " bytes from vector"); JSON_THROW(std::out_of_range("cannot read " + std::to_string(sizeof(T)) + " bytes from vector"));
} }
T result; T result;
@ -6900,19 +6916,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)
{ {
throw std::out_of_range("len out of range"); JSON_THROW(std::out_of_range("len out of range"));
} }
// 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)))
{ {
throw std::out_of_range("len+offset out of range"); JSON_THROW(std::out_of_range("len+offset out of range"));
} }
// 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)
{ {
throw std::out_of_range("len+offset out of range"); JSON_THROW(std::out_of_range("len+offset out of range"));
} }
} }
@ -7148,7 +7164,7 @@ class basic_json
default: default:
{ {
throw std::invalid_argument("error parsing a msgpack @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))); JSON_THROW(std::invalid_argument("error parsing a msgpack @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))));
} }
} }
} }
@ -7631,7 +7647,7 @@ class basic_json
default: // anything else (0xFF is handled inside the other types) default: // anything else (0xFF is handled inside the other types)
{ {
throw std::invalid_argument("error parsing a CBOR @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))); JSON_THROW(std::invalid_argument("error parsing a CBOR @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))));
} }
} }
} }
@ -8521,7 +8537,7 @@ class basic_json
case basic_json::value_t::null: case basic_json::value_t::null:
{ {
throw std::out_of_range("cannot get value"); JSON_THROW(std::out_of_range("cannot get value"));
} }
default: default:
@ -8531,7 +8547,7 @@ class basic_json
return *m_object; return *m_object;
} }
throw std::out_of_range("cannot get value"); JSON_THROW(std::out_of_range("cannot get value"));
} }
} }
} }
@ -8565,7 +8581,7 @@ class basic_json
return m_object; return m_object;
} }
throw std::out_of_range("cannot get value"); JSON_THROW(std::out_of_range("cannot get value"));
} }
} }
} }
@ -8665,7 +8681,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)
{ {
throw std::domain_error("cannot compare iterators of different containers"); JSON_THROW(std::domain_error("cannot compare iterators of different containers"));
} }
assert(m_object != nullptr); assert(m_object != nullptr);
@ -8707,7 +8723,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)
{ {
throw std::domain_error("cannot compare iterators of different containers"); JSON_THROW(std::domain_error("cannot compare iterators of different containers"));
} }
assert(m_object != nullptr); assert(m_object != nullptr);
@ -8716,7 +8732,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
throw std::domain_error("cannot compare order of object iterators"); JSON_THROW(std::domain_error("cannot compare order of object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
@ -8770,7 +8786,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
throw std::domain_error("cannot use offsets with object iterators"); JSON_THROW(std::domain_error("cannot use offsets with object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
@ -8832,7 +8848,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
throw std::domain_error("cannot use offsets with object iterators"); JSON_THROW(std::domain_error("cannot use offsets with object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
@ -8859,7 +8875,7 @@ class basic_json
{ {
case basic_json::value_t::object: case basic_json::value_t::object:
{ {
throw std::domain_error("cannot use operator[] for object iterators"); JSON_THROW(std::domain_error("cannot use operator[] for object iterators"));
} }
case basic_json::value_t::array: case basic_json::value_t::array:
@ -8869,7 +8885,7 @@ class basic_json
case basic_json::value_t::null: case basic_json::value_t::null:
{ {
throw std::out_of_range("cannot get value"); JSON_THROW(std::out_of_range("cannot get value"));
} }
default: default:
@ -8879,7 +8895,7 @@ class basic_json
return *m_object; return *m_object;
} }
throw std::out_of_range("cannot get value"); JSON_THROW(std::out_of_range("cannot get value"));
} }
} }
} }
@ -8897,7 +8913,7 @@ class basic_json
return m_it.object_iterator->first; return m_it.object_iterator->first;
} }
throw std::domain_error("cannot use key() for non-object iterators"); JSON_THROW(std::domain_error("cannot use key() for non-object iterators"));
} }
/*! /*!
@ -9082,7 +9098,7 @@ class basic_json
// immediately abort if stream is erroneous // immediately abort if stream is erroneous
if (s.fail()) if (s.fail())
{ {
throw std::invalid_argument("stream error"); JSON_THROW(std::invalid_argument("stream error"));
} }
// fill buffer // fill buffer
@ -9149,7 +9165,7 @@ class basic_json
} }
else else
{ {
throw std::invalid_argument("missing or wrong low surrogate"); JSON_THROW(std::invalid_argument("missing or wrong low surrogate"));
} }
} }
@ -9183,7 +9199,7 @@ class basic_json
} }
else else
{ {
throw std::out_of_range("code points above 0x10FFFF are invalid"); JSON_THROW(std::out_of_range("code points above 0x10FFFF are invalid"));
} }
return result; return result;
@ -9565,7 +9581,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')
{ {
throw std::invalid_argument("missing low surrogate"); JSON_THROW(std::invalid_argument("missing low surrogate"));
} }
// get code yyyy from uxxxx\uyyyy // get code yyyy from uxxxx\uyyyy
@ -9578,7 +9594,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
throw std::invalid_argument("missing high surrogate"); JSON_THROW(std::invalid_argument("missing high surrogate"));
} }
else else
{ {
@ -10056,7 +10072,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);
throw std::invalid_argument(error_msg); JSON_THROW(std::invalid_argument(error_msg));
} }
} }
@ -10068,7 +10084,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));
throw std::invalid_argument(error_msg); JSON_THROW(std::invalid_argument(error_msg));
} }
} }
@ -10164,7 +10180,7 @@ class basic_json
{ {
if (is_root()) if (is_root())
{ {
throw std::domain_error("JSON pointer has no parent"); JSON_THROW(std::domain_error("JSON pointer has no parent"));
} }
auto last = reference_tokens.back(); auto last = reference_tokens.back();
@ -10182,7 +10198,7 @@ class basic_json
{ {
if (is_root()) if (is_root())
{ {
throw std::domain_error("JSON pointer has no parent"); JSON_THROW(std::domain_error("JSON pointer has no parent"));
} }
json_pointer result = *this; json_pointer result = *this;
@ -10243,7 +10259,7 @@ class basic_json
*/ */
default: default:
{ {
throw std::domain_error("invalid value to unflatten"); JSON_THROW(std::domain_error("invalid value to unflatten"));
} }
} }
} }
@ -10311,7 +10327,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')
{ {
throw std::domain_error("array index must not begin with '0'"); JSON_THROW(std::domain_error("array index must not begin with '0'"));
} }
if (reference_token == "-") if (reference_token == "-")
@ -10329,7 +10345,7 @@ class basic_json
default: default:
{ {
throw std::out_of_range("unresolved reference token '" + reference_token + "'"); JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
} }
} }
} }
@ -10363,7 +10379,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')
{ {
throw std::domain_error("array index must not begin with '0'"); JSON_THROW(std::domain_error("array index must not begin with '0'"));
} }
// note: at performs range check // note: at performs range check
@ -10373,7 +10389,7 @@ class basic_json
default: default:
{ {
throw std::out_of_range("unresolved reference token '" + reference_token + "'"); JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
} }
} }
} }
@ -10415,7 +10431,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')
{ {
throw std::domain_error("array index must not begin with '0'"); JSON_THROW(std::domain_error("array index must not begin with '0'"));
} }
// use unchecked array access // use unchecked array access
@ -10425,7 +10441,7 @@ class basic_json
default: default:
{ {
throw std::out_of_range("unresolved reference token '" + reference_token + "'"); JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
} }
} }
} }
@ -10459,7 +10475,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')
{ {
throw std::domain_error("array index must not begin with '0'"); JSON_THROW(std::domain_error("array index must not begin with '0'"));
} }
// note: at performs range check // note: at performs range check
@ -10469,7 +10485,7 @@ class basic_json
default: default:
{ {
throw std::out_of_range("unresolved reference token '" + reference_token + "'"); JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
} }
} }
} }
@ -10491,7 +10507,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] != '/')
{ {
throw std::domain_error("JSON pointer must be empty or begin with '/'"); JSON_THROW(std::domain_error("JSON pointer must be empty or begin with '/'"));
} }
// extract the reference tokens: // extract the reference tokens:
@ -10526,7 +10542,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'))
{ {
throw std::domain_error("escape error: '~' must be followed with '0' or '1'"); JSON_THROW(std::domain_error("escape error: '~' must be followed with '0' or '1'"));
} }
} }
@ -10652,7 +10668,7 @@ class basic_json
{ {
if (not value.is_object()) if (not value.is_object())
{ {
throw std::domain_error("only objects can be unflattened"); JSON_THROW(std::domain_error("only objects can be unflattened"));
} }
basic_json result; basic_json result;
@ -10662,7 +10678,7 @@ class basic_json
{ {
if (not element.second.is_primitive()) if (not element.second.is_primitive())
{ {
throw std::domain_error("values in object must be primitive"); JSON_THROW(std::domain_error("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
@ -10991,7 +11007,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
throw std::out_of_range("array index " + std::to_string(idx) + " is out of range"); JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
} }
else else
{ {
@ -11029,7 +11045,7 @@ class basic_json
} }
else else
{ {
throw std::out_of_range("key '" + last_path + "' not found"); JSON_THROW(std::out_of_range("key '" + last_path + "' not found"));
} }
} }
else if (parent.is_array()) else if (parent.is_array())
@ -11043,7 +11059,7 @@ class basic_json
if (not json_patch.is_array()) if (not json_patch.is_array())
{ {
// a JSON patch must be an array of objects // a JSON patch must be an array of objects
throw std::invalid_argument("JSON patch must be an array of objects"); JSON_THROW(std::invalid_argument("JSON patch must be an array of objects"));
} }
// iterate and apply th eoperations // iterate and apply th eoperations
@ -11063,13 +11079,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())
{ {
throw std::invalid_argument(error_msg + " must have member '" + member + "'"); JSON_THROW(std::invalid_argument(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())
{ {
throw std::invalid_argument(error_msg + " must have string member '" + member + "'"); JSON_THROW(std::invalid_argument(error_msg + " must have string member '" + member + "'"));
} }
// no error: return value // no error: return value
@ -11079,7 +11095,7 @@ class basic_json
// type check // type check
if (not val.is_object()) if (not val.is_object())
{ {
throw std::invalid_argument("JSON patch must be an array of objects"); JSON_THROW(std::invalid_argument("JSON patch must be an array of objects"));
} }
// collect mandatory members // collect mandatory members
@ -11138,13 +11154,13 @@ class basic_json
case patch_operations::test: case patch_operations::test:
{ {
bool success = false; bool success = false;
try JSON_TRY
{ {
// check if "value" matches the one at "path" // check if "value" matches the one at "path"
// the "path" location must exist - use at() // the "path" location must exist - use at()
success = (result.at(ptr) == get_value("test", "value", false)); success = (result.at(ptr) == get_value("test", "value", false));
} }
catch (std::out_of_range&) JSON_CATCH (std::out_of_range&)
{ {
// ignore out of range errors: success remains false // ignore out of range errors: success remains false
} }
@ -11152,7 +11168,7 @@ class basic_json
// throw an exception if test fails // throw an exception if test fails
if (not success) if (not success)
{ {
throw std::domain_error("unsuccessful: " + val.dump()); JSON_THROW(std::domain_error("unsuccessful: " + val.dump()));
} }
break; break;
@ -11162,7 +11178,7 @@ class basic_json
{ {
// op must be "add", "remove", "replace", "move", "copy", or // op must be "add", "remove", "replace", "move", "copy", or
// "test" // "test"
throw std::invalid_argument("operation value '" + op + "' is invalid"); JSON_THROW(std::invalid_argument("operation value '" + op + "' is invalid"));
} }
} }
} }
@ -11435,4 +11451,10 @@ inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
// clean up
#undef JSON_THROW
#undef JSON_TRY
#undef JSON_CATCH
#undef JSON_DEPRECATED
#endif #endif

View file

@ -75,7 +75,7 @@ test-%: src/unit-%.cpp ../src/json.hpp thirdparty/catch/catch.hpp
@echo "[CXXLD] $@" @echo "[CXXLD] $@"
@$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -DCATCH_CONFIG_MAIN $< -o $@ @$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -DCATCH_CONFIG_MAIN $< -o $@
TEST_PATTERN = "*" TEST_PATTERN ?= "*"
TEST_PREFIX = "" TEST_PREFIX = ""
check: $(TESTCASES) check: $(TESTCASES)
@cd .. ; for testcase in $(TESTCASES); do echo "Executing $$testcase..."; $(TEST_PREFIX)test/$$testcase $(TEST_PATTERN) || exit 1; done @cd .. ; for testcase in $(TESTCASES); do echo "Executing $$testcase..."; $(TEST_PREFIX)test/$$testcase $(TEST_PATTERN) || exit 1; done

View file

@ -1187,7 +1187,7 @@ TEST_CASE("single CBOR roundtrip")
} }
} }
TEST_CASE("CBOR regressions") TEST_CASE("CBOR regressions", "[!throws]")
{ {
SECTION("fuzz test results") SECTION("fuzz test results")
{ {

View file

@ -298,25 +298,6 @@ TEST_CASE("element access 2")
CHECK(j_const.value("/array"_json_pointer, json({10, 100})) == json({1, 2, 3})); CHECK(j_const.value("/array"_json_pointer, json({10, 100})) == json({1, 2, 3}));
} }
SECTION("access non-existing value")
{
CHECK(j.value("/not/existing"_json_pointer, 2) == 2);
CHECK(j.value("/not/existing"_json_pointer, 2u) == 2u);
CHECK(j.value("/not/existing"_json_pointer, false) == false);
CHECK(j.value("/not/existing"_json_pointer, "bar") == "bar");
CHECK(j.value("/not/existing"_json_pointer, 12.34) == Approx(12.34));
CHECK(j.value("/not/existing"_json_pointer, json({{"foo", "bar"}})) == json({{"foo", "bar"}}));
CHECK(j.value("/not/existing"_json_pointer, json({10, 100})) == json({10, 100}));
CHECK(j_const.value("/not/existing"_json_pointer, 2) == 2);
CHECK(j_const.value("/not/existing"_json_pointer, 2u) == 2u);
CHECK(j_const.value("/not/existing"_json_pointer, false) == false);
CHECK(j_const.value("/not/existing"_json_pointer, "bar") == "bar");
CHECK(j_const.value("/not/existing"_json_pointer, 12.34) == Approx(12.34));
CHECK(j_const.value("/not/existing"_json_pointer, json({{"foo", "bar"}})) == json({{"foo", "bar"}}));
CHECK(j_const.value("/not/existing"_json_pointer, json({10, 100})) == json({10, 100}));
}
SECTION("access on non-object type") SECTION("access on non-object type")
{ {
SECTION("null") SECTION("null")
@ -957,3 +938,37 @@ TEST_CASE("element access 2")
} }
} }
} }
TEST_CASE("element access 2 (throwing tests)", "[!throws]")
{
SECTION("object")
{
json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", json::object()}, {"array", {1, 2, 3}}};
const json j_const = j;
SECTION("access specified element with default value")
{
SECTION("given a JSON pointer")
{
SECTION("access non-existing value")
{
CHECK(j.value("/not/existing"_json_pointer, 2) == 2);
CHECK(j.value("/not/existing"_json_pointer, 2u) == 2u);
CHECK(j.value("/not/existing"_json_pointer, false) == false);
CHECK(j.value("/not/existing"_json_pointer, "bar") == "bar");
CHECK(j.value("/not/existing"_json_pointer, 12.34) == Approx(12.34));
CHECK(j.value("/not/existing"_json_pointer, json({{"foo", "bar"}})) == json({{"foo", "bar"}}));
CHECK(j.value("/not/existing"_json_pointer, json({10, 100})) == json({10, 100}));
CHECK(j_const.value("/not/existing"_json_pointer, 2) == 2);
CHECK(j_const.value("/not/existing"_json_pointer, 2u) == 2u);
CHECK(j_const.value("/not/existing"_json_pointer, false) == false);
CHECK(j_const.value("/not/existing"_json_pointer, "bar") == "bar");
CHECK(j_const.value("/not/existing"_json_pointer, 12.34) == Approx(12.34));
CHECK(j_const.value("/not/existing"_json_pointer, json({{"foo", "bar"}})) == json({{"foo", "bar"}}));
CHECK(j_const.value("/not/existing"_json_pointer, json({10, 100})) == json({10, 100}));
}
}
}
}
}