Commit 76e5e29e by Niels

overworked exceptions and tests (#160)

parent 8620583c
...@@ -42,8 +42,8 @@ to the files you want to use JSON objects. That's it. Do not forget to set the n ...@@ -42,8 +42,8 @@ to the files you want to use JSON objects. That's it. Do not forget to set the n
Though it's 2015 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work: Though it's 2015 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
- GCC 4.9 - 5.2 (and possibly later) - GCC 4.9 - 6.0 (and possibly later)
- Clang 3.4 - 3.7 (and possibly later) - Clang 3.4 - 3.8 (and possibly later)
- Microsoft Visual C++ 14.0 RC (and possibly later) - Microsoft Visual C++ 14.0 RC (and possibly later)
I would be happy to learn about other compilers/versions. I would be happy to learn about other compilers/versions.
......
...@@ -1359,7 +1359,8 @@ class basic_json ...@@ -1359,7 +1359,8 @@ class basic_json
@throw std::domain_error if @a type_deduction is `false`, @a manual_type is @throw std::domain_error if @a type_deduction is `false`, @a manual_type is
`value_t::object`, but @a init contains an element which is not a pair `value_t::object`, but @a init contains an element which is not a pair
whose first element is a string whose first element is a string; example: `"cannot create object from
initializer list"`
@complexity Linear in the size of the initializer list @a init. @complexity Linear in the size of the initializer list @a init.
...@@ -1552,11 +1553,13 @@ class basic_json ...@@ -1552,11 +1553,13 @@ class basic_json
@param[in] last end of the range to copy from (excluded) @param[in] last end of the range to copy from (excluded)
@throw std::domain_error if iterators are not compatible; that is, do not @throw std::domain_error if iterators are not compatible; that is, do not
belong to the same JSON value belong to the same JSON value; example: `"iterators are not compatible"`
@throw std::out_of_range if iterators are for a primitive type (number, @throw std::out_of_range if iterators are for a primitive type (number,
boolean, or string) where an out of range error can be detected easily boolean, or string) where an out of range error can be detected easily;
example: `"iterators out of range"`
@throw std::bad_alloc if allocation for object, array, or string fails @throw std::bad_alloc if allocation for object, array, or string fails
@throw std::domain_error if called with a null value @throw std::domain_error if called with a null value; example: `"cannot use
construct with iterators from null"`
@complexity Linear in distance between @a first and @a last. @complexity Linear in distance between @a first and @a last.
...@@ -2412,7 +2415,7 @@ class basic_json ...@@ -2412,7 +2415,7 @@ class basic_json
@return copy of the JSON value, converted to type @a ValueType @return copy of the JSON value, converted to type @a ValueType
@throw std::domain_error in case passed type @a ValueType is incompatible @throw std::domain_error in case passed type @a ValueType is incompatible
to JSON to JSON; example: `"type must be object, but is null"`
@complexity Linear in the size of the JSON value. @complexity Linear in the size of the JSON value.
...@@ -2785,7 +2788,8 @@ class basic_json ...@@ -2785,7 +2788,8 @@ class basic_json
@return reference to the element at index @a idx @return reference to the element at index @a idx
@throw std::domain_error if JSON is not an array or null @throw std::domain_error if JSON is not an array or null; example: `"cannot
use operator[] with null"`
@complexity Constant if @a idx is in the range of the array. Otherwise @complexity Constant if @a idx is in the range of the array. Otherwise
linear in `idx - size()`. linear in `idx - size()`.
...@@ -2830,7 +2834,8 @@ class basic_json ...@@ -2830,7 +2834,8 @@ class basic_json
@return const reference to the element at index @a idx @return const reference to the element at index @a idx
@throw std::domain_error if JSON is not an array @throw std::domain_error if JSON is not an array; example: `"cannot use
operator[] with null"`
@complexity Constant. @complexity Constant.
...@@ -2865,7 +2870,8 @@ class basic_json ...@@ -2865,7 +2870,8 @@ class basic_json
@return reference to the element at key @a key @return reference to the element at key @a key
@throw std::domain_error if JSON is not an object or null @throw std::domain_error if JSON is not an object or null; example:
`"cannot use operator[] with null"`
@complexity Logarithmic in the size of the container. @complexity Logarithmic in the size of the container.
...@@ -2911,7 +2917,8 @@ class basic_json ...@@ -2911,7 +2917,8 @@ class basic_json
@return const reference to the element at key @a key @return const reference to the element at key @a key
@throw std::domain_error if JSON is not an object @throw std::domain_error if JSON is not an object; example: `"cannot use
operator[] with null"`
@complexity Logarithmic in the size of the container. @complexity Logarithmic in the size of the container.
...@@ -2952,7 +2959,8 @@ class basic_json ...@@ -2952,7 +2959,8 @@ class basic_json
@return reference to the element at key @a key @return reference to the element at key @a key
@throw std::domain_error if JSON is not an object or null @throw std::domain_error if JSON is not an object or null; example:
`"cannot use operator[] with null"`
@complexity Logarithmic in the size of the container. @complexity Logarithmic in the size of the container.
...@@ -3001,7 +3009,8 @@ class basic_json ...@@ -3001,7 +3009,8 @@ class basic_json
@return const reference to the element at key @a key @return const reference to the element at key @a key
@throw std::domain_error if JSON is not an object @throw std::domain_error if JSON is not an object; example: `"cannot use
operator[] with null"`
@complexity Logarithmic in the size of the container. @complexity Logarithmic in the size of the container.
...@@ -3061,7 +3070,8 @@ class basic_json ...@@ -3061,7 +3070,8 @@ class basic_json
@return copy of the element at key @a key or @a default_value if @a key @return copy of the element at key @a key or @a default_value if @a key
is not found is not found
@throw std::domain_error if JSON is not an object @throw std::domain_error if JSON is not an object; example: `"cannot use
value() with null"`
@complexity Logarithmic in the size of the container. @complexity Logarithmic in the size of the container.
...@@ -3199,11 +3209,13 @@ class basic_json ...@@ -3199,11 +3209,13 @@ class basic_json
@tparam InteratorType an @ref iterator or @ref const_iterator @tparam InteratorType an @ref iterator or @ref const_iterator
@throw std::domain_error if called on a `null` value @throw std::domain_error if called on a `null` value; example: `"cannot use
erase() with null"`
@throw std::domain_error if called on an iterator which does not belong to @throw std::domain_error if called on an iterator which does not belong to
the current JSON value the current JSON value; example: `"iterator does not fit current value"`
@throw std::out_of_range if called on a primitive type with invalid @throw std::out_of_range if called on a primitive type with invalid
iterator (i.e., any iterator which is not end()) iterator (i.e., any iterator which is not end()); example: `"iterator out
of range"`
@complexity The complexity depends on the type: @complexity The complexity depends on the type:
- objects: amortized constant - objects: amortized constant
...@@ -3300,11 +3312,13 @@ class basic_json ...@@ -3300,11 +3312,13 @@ class basic_json
@tparam InteratorType an @ref iterator or @ref const_iterator @tparam InteratorType an @ref iterator or @ref const_iterator
@throw std::domain_error if called on a `null` value @throw std::domain_error if called on a `null` value; example: `"cannot use
erase() with null"`
@throw std::domain_error if called on iterators which does not belong to @throw std::domain_error if called on iterators which does not belong to
the current JSON value the current JSON value; example: `"iterators do not fit current value"`
@throw std::out_of_range if called on a primitive type with invalid @throw std::out_of_range if called on a primitive type with invalid
iterators (i.e., if `first != begin()` and `last != end()`) iterators (i.e., if `first != begin()` and `last != end()`); example:
`"iterators out of range"`
@complexity The complexity depends on the type: @complexity The complexity depends on the type:
- objects: `log(size()) + std::distance(first, last)` - objects: `log(size()) + std::distance(first, last)`
...@@ -3378,7 +3392,7 @@ class basic_json ...@@ -3378,7 +3392,7 @@ class basic_json
default: default:
{ {
throw std::domain_error("cannot use erase with " + type_name()); throw std::domain_error("cannot use erase() with " + type_name());
} }
} }
...@@ -3396,7 +3410,8 @@ class basic_json ...@@ -3396,7 +3410,8 @@ class basic_json
type, the return value will always be `0` (@a key was not found) or `1` (@a type, the return value will always be `0` (@a key was not found) or `1` (@a
key was found). key was found).
@throw std::domain_error when called on a type other than JSON object @throw std::domain_error when called on a type other than JSON object;
example: `"cannot use erase() with null"`
@complexity `log(size()) + count(key)` @complexity `log(size()) + count(key)`
...@@ -3430,8 +3445,10 @@ class basic_json ...@@ -3430,8 +3445,10 @@ class basic_json
@param[in] idx index of the element to remove @param[in] idx index of the element to remove
@throw std::domain_error when called on a type other than JSON array @throw std::domain_error when called on a type other than JSON array;
@throw std::out_of_range when `idx >= size()` example: `"cannot use erase() with null"`
@throw std::out_of_range when `idx >= size()`; example: `"index out of
range"`
@complexity Linear in distance between @a idx and the end of the container. @complexity Linear in distance between @a idx and the end of the container.
...@@ -4065,7 +4082,8 @@ class basic_json ...@@ -4065,7 +4082,8 @@ class basic_json
@param val the value to add to the JSON array @param val the value to add to the JSON array
@throw std::domain_error when called on a type other than JSON array or null @throw std::domain_error when called on a type other than JSON array or
null; example: `"cannot use push_back() with number"`
@complexity Amortized constant. @complexity Amortized constant.
...@@ -4149,7 +4167,7 @@ class basic_json ...@@ -4149,7 +4167,7 @@ class basic_json
@param[in] val the value to add to the JSON object @param[in] val the value to add to the JSON object
@throw std::domain_error when called on a type other than JSON object or @throw std::domain_error when called on a type other than JSON object or
null null; example: `"cannot use push_back() with number"`
@complexity Logarithmic in the size of the container, O(log(`size()`)). @complexity Logarithmic in the size of the container, O(log(`size()`)).
...@@ -4199,7 +4217,8 @@ class basic_json ...@@ -4199,7 +4217,8 @@ class basic_json
@return iterator pointing to the inserted @a val. @return iterator pointing to the inserted @a val.
@throw std::domain_error if called on JSON values other than arrays @throw std::domain_error if called on JSON values other than arrays
@throw std::domain_error if @a pos is not an iterator of *this @throw std::domain_error if @a pos is not an iterator of *this; example:
`"iterator does not fit current value"`
@complexity Constant plus linear in the distance between pos and end of the @complexity Constant plus linear in the distance between pos and end of the
container. container.
...@@ -4252,7 +4271,8 @@ class basic_json ...@@ -4252,7 +4271,8 @@ class basic_json
`cnt==0` `cnt==0`
@throw std::domain_error if called on JSON values other than arrays @throw std::domain_error if called on JSON values other than arrays
@throw std::domain_error if @a pos is not an iterator of *this @throw std::domain_error if @a pos is not an iterator of *this; example:
`"iterator does not fit current value"`
@complexity Linear in @a cnt plus linear in the distance between @a pos @complexity Linear in @a cnt plus linear in the distance between @a pos
and end of the container. and end of the container.
...@@ -4294,11 +4314,14 @@ class basic_json ...@@ -4294,11 +4314,14 @@ class basic_json
@param[in] last end of the range of elements to insert @param[in] last end of the range of elements to insert
@throw std::domain_error if called on JSON values other than arrays @throw std::domain_error if called on JSON values other than arrays
@throw std::domain_error if @a pos is not an iterator of *this @throw std::domain_error if @a pos is not an iterator of *this; example:
`"iterator does not fit current value"`
@throw std::domain_error if @a first and @a last do not belong to the same @throw std::domain_error if @a first and @a last do not belong to the same
JSON value JSON value; example: `"iterators do not fit"`
@throw std::domain_error if @a first or @a last are iterators into @throw std::domain_error if @a first or @a last are iterators into
container for which insert is called container for which insert is called; example: `"passed iterators may not
belong to container"`
@return iterator pointing to the first element inserted, or @a pos if @return iterator pointing to the first element inserted, or @a pos if
`first==last` `first==last`
...@@ -4352,7 +4375,8 @@ class basic_json ...@@ -4352,7 +4375,8 @@ class basic_json
@param[in] ilist initializer list to insert the values from @param[in] ilist initializer list to insert the values from
@throw std::domain_error if called on JSON values other than arrays @throw std::domain_error if called on JSON values other than arrays
@throw std::domain_error if @a pos is not an iterator of *this @throw std::domain_error if @a pos is not an iterator of *this; example:
`"iterator does not fit current value"`
@return iterator pointing to the first element inserted, or @a pos if @return iterator pointing to the first element inserted, or @a pos if
`ilist` is empty `ilist` is empty
...@@ -5870,7 +5894,7 @@ class basic_json ...@@ -5870,7 +5894,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"); throw std::domain_error("cannot compare order of object iterators");
} }
case basic_json::value_t::array: case basic_json::value_t::array:
...@@ -5910,7 +5934,7 @@ class basic_json ...@@ -5910,7 +5934,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"); throw std::domain_error("cannot use offsets with object iterators");
} }
case basic_json::value_t::array: case basic_json::value_t::array:
...@@ -5958,7 +5982,7 @@ class basic_json ...@@ -5958,7 +5982,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"); throw std::domain_error("cannot use offsets with object iterators");
} }
case basic_json::value_t::array: case basic_json::value_t::array:
......
...@@ -1359,7 +1359,8 @@ class basic_json ...@@ -1359,7 +1359,8 @@ class basic_json
@throw std::domain_error if @a type_deduction is `false`, @a manual_type is @throw std::domain_error if @a type_deduction is `false`, @a manual_type is
`value_t::object`, but @a init contains an element which is not a pair `value_t::object`, but @a init contains an element which is not a pair
whose first element is a string whose first element is a string; example: `"cannot create object from
initializer list"`
@complexity Linear in the size of the initializer list @a init. @complexity Linear in the size of the initializer list @a init.
...@@ -1552,11 +1553,13 @@ class basic_json ...@@ -1552,11 +1553,13 @@ class basic_json
@param[in] last end of the range to copy from (excluded) @param[in] last end of the range to copy from (excluded)
@throw std::domain_error if iterators are not compatible; that is, do not @throw std::domain_error if iterators are not compatible; that is, do not
belong to the same JSON value belong to the same JSON value; example: `"iterators are not compatible"`
@throw std::out_of_range if iterators are for a primitive type (number, @throw std::out_of_range if iterators are for a primitive type (number,
boolean, or string) where an out of range error can be detected easily boolean, or string) where an out of range error can be detected easily;
example: `"iterators out of range"`
@throw std::bad_alloc if allocation for object, array, or string fails @throw std::bad_alloc if allocation for object, array, or string fails
@throw std::domain_error if called with a null value @throw std::domain_error if called with a null value; example: `"cannot use
construct with iterators from null"`
@complexity Linear in distance between @a first and @a last. @complexity Linear in distance between @a first and @a last.
...@@ -2412,7 +2415,7 @@ class basic_json ...@@ -2412,7 +2415,7 @@ class basic_json
@return copy of the JSON value, converted to type @a ValueType @return copy of the JSON value, converted to type @a ValueType
@throw std::domain_error in case passed type @a ValueType is incompatible @throw std::domain_error in case passed type @a ValueType is incompatible
to JSON to JSON; example: `"type must be object, but is null"`
@complexity Linear in the size of the JSON value. @complexity Linear in the size of the JSON value.
...@@ -2785,7 +2788,8 @@ class basic_json ...@@ -2785,7 +2788,8 @@ class basic_json
@return reference to the element at index @a idx @return reference to the element at index @a idx
@throw std::domain_error if JSON is not an array or null @throw std::domain_error if JSON is not an array or null; example: `"cannot
use operator[] with null"`
@complexity Constant if @a idx is in the range of the array. Otherwise @complexity Constant if @a idx is in the range of the array. Otherwise
linear in `idx - size()`. linear in `idx - size()`.
...@@ -2830,7 +2834,8 @@ class basic_json ...@@ -2830,7 +2834,8 @@ class basic_json
@return const reference to the element at index @a idx @return const reference to the element at index @a idx
@throw std::domain_error if JSON is not an array @throw std::domain_error if JSON is not an array; example: `"cannot use
operator[] with null"`
@complexity Constant. @complexity Constant.
...@@ -2865,7 +2870,8 @@ class basic_json ...@@ -2865,7 +2870,8 @@ class basic_json
@return reference to the element at key @a key @return reference to the element at key @a key
@throw std::domain_error if JSON is not an object or null @throw std::domain_error if JSON is not an object or null; example:
`"cannot use operator[] with null"`
@complexity Logarithmic in the size of the container. @complexity Logarithmic in the size of the container.
...@@ -2911,7 +2917,8 @@ class basic_json ...@@ -2911,7 +2917,8 @@ class basic_json
@return const reference to the element at key @a key @return const reference to the element at key @a key
@throw std::domain_error if JSON is not an object @throw std::domain_error if JSON is not an object; example: `"cannot use
operator[] with null"`
@complexity Logarithmic in the size of the container. @complexity Logarithmic in the size of the container.
...@@ -2952,7 +2959,8 @@ class basic_json ...@@ -2952,7 +2959,8 @@ class basic_json
@return reference to the element at key @a key @return reference to the element at key @a key
@throw std::domain_error if JSON is not an object or null @throw std::domain_error if JSON is not an object or null; example:
`"cannot use operator[] with null"`
@complexity Logarithmic in the size of the container. @complexity Logarithmic in the size of the container.
...@@ -3001,7 +3009,8 @@ class basic_json ...@@ -3001,7 +3009,8 @@ class basic_json
@return const reference to the element at key @a key @return const reference to the element at key @a key
@throw std::domain_error if JSON is not an object @throw std::domain_error if JSON is not an object; example: `"cannot use
operator[] with null"`
@complexity Logarithmic in the size of the container. @complexity Logarithmic in the size of the container.
...@@ -3061,7 +3070,8 @@ class basic_json ...@@ -3061,7 +3070,8 @@ class basic_json
@return copy of the element at key @a key or @a default_value if @a key @return copy of the element at key @a key or @a default_value if @a key
is not found is not found
@throw std::domain_error if JSON is not an object @throw std::domain_error if JSON is not an object; example: `"cannot use
value() with null"`
@complexity Logarithmic in the size of the container. @complexity Logarithmic in the size of the container.
...@@ -3199,11 +3209,13 @@ class basic_json ...@@ -3199,11 +3209,13 @@ class basic_json
@tparam InteratorType an @ref iterator or @ref const_iterator @tparam InteratorType an @ref iterator or @ref const_iterator
@throw std::domain_error if called on a `null` value @throw std::domain_error if called on a `null` value; example: `"cannot use
erase() with null"`
@throw std::domain_error if called on an iterator which does not belong to @throw std::domain_error if called on an iterator which does not belong to
the current JSON value the current JSON value; example: `"iterator does not fit current value"`
@throw std::out_of_range if called on a primitive type with invalid @throw std::out_of_range if called on a primitive type with invalid
iterator (i.e., any iterator which is not end()) iterator (i.e., any iterator which is not end()); example: `"iterator out
of range"`
@complexity The complexity depends on the type: @complexity The complexity depends on the type:
- objects: amortized constant - objects: amortized constant
...@@ -3300,11 +3312,13 @@ class basic_json ...@@ -3300,11 +3312,13 @@ class basic_json
@tparam InteratorType an @ref iterator or @ref const_iterator @tparam InteratorType an @ref iterator or @ref const_iterator
@throw std::domain_error if called on a `null` value @throw std::domain_error if called on a `null` value; example: `"cannot use
erase() with null"`
@throw std::domain_error if called on iterators which does not belong to @throw std::domain_error if called on iterators which does not belong to
the current JSON value the current JSON value; example: `"iterators do not fit current value"`
@throw std::out_of_range if called on a primitive type with invalid @throw std::out_of_range if called on a primitive type with invalid
iterators (i.e., if `first != begin()` and `last != end()`) iterators (i.e., if `first != begin()` and `last != end()`); example:
`"iterators out of range"`
@complexity The complexity depends on the type: @complexity The complexity depends on the type:
- objects: `log(size()) + std::distance(first, last)` - objects: `log(size()) + std::distance(first, last)`
...@@ -3378,7 +3392,7 @@ class basic_json ...@@ -3378,7 +3392,7 @@ class basic_json
default: default:
{ {
throw std::domain_error("cannot use erase with " + type_name()); throw std::domain_error("cannot use erase() with " + type_name());
} }
} }
...@@ -3396,7 +3410,8 @@ class basic_json ...@@ -3396,7 +3410,8 @@ class basic_json
type, the return value will always be `0` (@a key was not found) or `1` (@a type, the return value will always be `0` (@a key was not found) or `1` (@a
key was found). key was found).
@throw std::domain_error when called on a type other than JSON object @throw std::domain_error when called on a type other than JSON object;
example: `"cannot use erase() with null"`
@complexity `log(size()) + count(key)` @complexity `log(size()) + count(key)`
...@@ -3430,8 +3445,10 @@ class basic_json ...@@ -3430,8 +3445,10 @@ class basic_json
@param[in] idx index of the element to remove @param[in] idx index of the element to remove
@throw std::domain_error when called on a type other than JSON array @throw std::domain_error when called on a type other than JSON array;
@throw std::out_of_range when `idx >= size()` example: `"cannot use erase() with null"`
@throw std::out_of_range when `idx >= size()`; example: `"index out of
range"`
@complexity Linear in distance between @a idx and the end of the container. @complexity Linear in distance between @a idx and the end of the container.
...@@ -4065,7 +4082,8 @@ class basic_json ...@@ -4065,7 +4082,8 @@ class basic_json
@param val the value to add to the JSON array @param val the value to add to the JSON array
@throw std::domain_error when called on a type other than JSON array or null @throw std::domain_error when called on a type other than JSON array or
null; example: `"cannot use push_back() with number"`
@complexity Amortized constant. @complexity Amortized constant.
...@@ -4149,7 +4167,7 @@ class basic_json ...@@ -4149,7 +4167,7 @@ class basic_json
@param[in] val the value to add to the JSON object @param[in] val the value to add to the JSON object
@throw std::domain_error when called on a type other than JSON object or @throw std::domain_error when called on a type other than JSON object or
null null; example: `"cannot use push_back() with number"`
@complexity Logarithmic in the size of the container, O(log(`size()`)). @complexity Logarithmic in the size of the container, O(log(`size()`)).
...@@ -4199,7 +4217,8 @@ class basic_json ...@@ -4199,7 +4217,8 @@ class basic_json
@return iterator pointing to the inserted @a val. @return iterator pointing to the inserted @a val.
@throw std::domain_error if called on JSON values other than arrays @throw std::domain_error if called on JSON values other than arrays
@throw std::domain_error if @a pos is not an iterator of *this @throw std::domain_error if @a pos is not an iterator of *this; example:
`"iterator does not fit current value"`
@complexity Constant plus linear in the distance between pos and end of the @complexity Constant plus linear in the distance between pos and end of the
container. container.
...@@ -4252,7 +4271,8 @@ class basic_json ...@@ -4252,7 +4271,8 @@ class basic_json
`cnt==0` `cnt==0`
@throw std::domain_error if called on JSON values other than arrays @throw std::domain_error if called on JSON values other than arrays
@throw std::domain_error if @a pos is not an iterator of *this @throw std::domain_error if @a pos is not an iterator of *this; example:
`"iterator does not fit current value"`
@complexity Linear in @a cnt plus linear in the distance between @a pos @complexity Linear in @a cnt plus linear in the distance between @a pos
and end of the container. and end of the container.
...@@ -4294,11 +4314,14 @@ class basic_json ...@@ -4294,11 +4314,14 @@ class basic_json
@param[in] last end of the range of elements to insert @param[in] last end of the range of elements to insert
@throw std::domain_error if called on JSON values other than arrays @throw std::domain_error if called on JSON values other than arrays
@throw std::domain_error if @a pos is not an iterator of *this @throw std::domain_error if @a pos is not an iterator of *this; example:
`"iterator does not fit current value"`
@throw std::domain_error if @a first and @a last do not belong to the same @throw std::domain_error if @a first and @a last do not belong to the same
JSON value JSON value; example: `"iterators do not fit"`
@throw std::domain_error if @a first or @a last are iterators into @throw std::domain_error if @a first or @a last are iterators into
container for which insert is called container for which insert is called; example: `"passed iterators may not
belong to container"`
@return iterator pointing to the first element inserted, or @a pos if @return iterator pointing to the first element inserted, or @a pos if
`first==last` `first==last`
...@@ -4352,7 +4375,8 @@ class basic_json ...@@ -4352,7 +4375,8 @@ class basic_json
@param[in] ilist initializer list to insert the values from @param[in] ilist initializer list to insert the values from
@throw std::domain_error if called on JSON values other than arrays @throw std::domain_error if called on JSON values other than arrays
@throw std::domain_error if @a pos is not an iterator of *this @throw std::domain_error if @a pos is not an iterator of *this; example:
`"iterator does not fit current value"`
@return iterator pointing to the first element inserted, or @a pos if @return iterator pointing to the first element inserted, or @a pos if
`ilist` is empty `ilist` is empty
...@@ -5870,7 +5894,7 @@ class basic_json ...@@ -5870,7 +5894,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"); throw std::domain_error("cannot compare order of object iterators");
} }
case basic_json::value_t::array: case basic_json::value_t::array:
...@@ -5910,7 +5934,7 @@ class basic_json ...@@ -5910,7 +5934,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"); throw std::domain_error("cannot use offsets with object iterators");
} }
case basic_json::value_t::array: case basic_json::value_t::array:
...@@ -5958,7 +5982,7 @@ class basic_json ...@@ -5958,7 +5982,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"); throw std::domain_error("cannot use offsets with object iterators");
} }
case basic_json::value_t::array: case basic_json::value_t::array:
......
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#define CATCH_CONFIG_MAIN #define CATCH_CONFIG_MAIN
#include "catch.hpp" #include "catch.hpp"
// macro to check exception names (see https://github.com/philsquared/Catch/issues/563)
#define CHECK_THROWS_NAME(block, exception, name) { try { block; } catch ( exception &e ) { CHECK(e.what() == std::string(name)); } }
#include <array> #include <array>
#include <deque> #include <deque>
#include <forward_list> #include <forward_list>
...@@ -895,6 +898,8 @@ TEST_CASE("constructors") ...@@ -895,6 +898,8 @@ TEST_CASE("constructors")
SECTION("object with error") SECTION("object with error")
{ {
CHECK_THROWS_AS(json::object({ {"one", 1}, {"two", 2.2}, {"three", false}, 13 }), std::logic_error); CHECK_THROWS_AS(json::object({ {"one", 1}, {"two", 2.2}, {"three", false}, 13 }), std::logic_error);
CHECK_THROWS_NAME(json::object({ {"one", 1}, {"two", 2.2}, {"three", false}, 13 }),
std::logic_error, "cannot create object from initializer list");
} }
SECTION("empty array") SECTION("empty array")
...@@ -968,12 +973,20 @@ TEST_CASE("constructors") ...@@ -968,12 +973,20 @@ TEST_CASE("constructors")
json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17}}; json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17}};
CHECK_THROWS_AS(json(jobject.begin(), jobject2.end()), std::domain_error); CHECK_THROWS_AS(json(jobject.begin(), jobject2.end()), std::domain_error);
CHECK_THROWS_AS(json(jobject2.begin(), jobject.end()), std::domain_error); CHECK_THROWS_AS(json(jobject2.begin(), jobject.end()), std::domain_error);
CHECK_THROWS_NAME(json(jobject.begin(), jobject2.end()), std::domain_error,
"iterators are not compatible");
CHECK_THROWS_NAME(json(jobject2.begin(), jobject.end()), std::domain_error,
"iterators are not compatible");
} }
{ {
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}, {"d", false}, {"e", true}}; json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}, {"d", false}, {"e", true}};
json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17}}; json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17}};
CHECK_THROWS_AS(json(jobject.cbegin(), jobject2.cend()), std::domain_error); CHECK_THROWS_AS(json(jobject.cbegin(), jobject2.cend()), std::domain_error);
CHECK_THROWS_AS(json(jobject2.cbegin(), jobject.cend()), std::domain_error); CHECK_THROWS_AS(json(jobject2.cbegin(), jobject.cend()), std::domain_error);
CHECK_THROWS_NAME(json(jobject.cbegin(), jobject2.cend()), std::domain_error,
"iterators are not compatible");
CHECK_THROWS_NAME(json(jobject2.cbegin(), jobject.cend()), std::domain_error,
"iterators are not compatible");
} }
} }
} }
...@@ -1029,12 +1042,20 @@ TEST_CASE("constructors") ...@@ -1029,12 +1042,20 @@ TEST_CASE("constructors")
json jarray2 = {2, 3, 4, 5}; json jarray2 = {2, 3, 4, 5};
CHECK_THROWS_AS(json(jarray.begin(), jarray2.end()), std::domain_error); CHECK_THROWS_AS(json(jarray.begin(), jarray2.end()), std::domain_error);
CHECK_THROWS_AS(json(jarray2.begin(), jarray.end()), std::domain_error); CHECK_THROWS_AS(json(jarray2.begin(), jarray.end()), std::domain_error);
CHECK_THROWS_NAME(json(jarray.begin(), jarray2.end()), std::domain_error,
"iterators are not compatible");
CHECK_THROWS_NAME(json(jarray2.begin(), jarray.end()), std::domain_error,
"iterators are not compatible");
} }
{ {
json jarray = {1, 2, 3, 4}; json jarray = {1, 2, 3, 4};
json jarray2 = {2, 3, 4, 5}; json jarray2 = {2, 3, 4, 5};
CHECK_THROWS_AS(json(jarray.cbegin(), jarray2.cend()), std::domain_error); CHECK_THROWS_AS(json(jarray.cbegin(), jarray2.cend()), std::domain_error);
CHECK_THROWS_AS(json(jarray2.cbegin(), jarray.cend()), std::domain_error); CHECK_THROWS_AS(json(jarray2.cbegin(), jarray.cend()), std::domain_error);
CHECK_THROWS_NAME(json(jarray.cbegin(), jarray2.cend()), std::domain_error,
"iterators are not compatible");
CHECK_THROWS_NAME(json(jarray2.cbegin(), jarray.cend()), std::domain_error,
"iterators are not compatible");
} }
} }
} }
...@@ -1048,10 +1069,14 @@ TEST_CASE("constructors") ...@@ -1048,10 +1069,14 @@ TEST_CASE("constructors")
{ {
json j; json j;
CHECK_THROWS_AS(json(j.begin(), j.end()), std::domain_error); CHECK_THROWS_AS(json(j.begin(), j.end()), std::domain_error);
CHECK_THROWS_NAME(json(j.begin(), j.end()), std::domain_error,
"cannot use construct with iterators from null");
} }
{ {
json j; json j;
CHECK_THROWS_AS(json(j.cbegin(), j.cend()), std::domain_error); CHECK_THROWS_AS(json(j.cbegin(), j.cend()), std::domain_error);
CHECK_THROWS_NAME(json(j.cbegin(), j.cend()), std::domain_error,
"cannot use construct with iterators from null");
} }
} }
...@@ -1120,11 +1145,15 @@ TEST_CASE("constructors") ...@@ -1120,11 +1145,15 @@ TEST_CASE("constructors")
json j = "foo"; json j = "foo";
CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
CHECK_THROWS_NAME(json(j.end(), j.end()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(json(j.begin(), j.begin()), std::out_of_range, "iterators out of range");
} }
{ {
json j = "bar"; json j = "bar";
CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
CHECK_THROWS_NAME(json(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(json(j.cbegin(), j.cbegin()), std::out_of_range, "iterators out of range");
} }
} }
...@@ -1134,11 +1163,15 @@ TEST_CASE("constructors") ...@@ -1134,11 +1163,15 @@ TEST_CASE("constructors")
json j = false; json j = false;
CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
CHECK_THROWS_NAME(json(j.end(), j.end()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(json(j.begin(), j.begin()), std::out_of_range, "iterators out of range");
} }
{ {
json j = true; json j = true;
CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
CHECK_THROWS_NAME(json(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(json(j.cbegin(), j.cbegin()), std::out_of_range, "iterators out of range");
} }
} }
...@@ -1148,11 +1181,15 @@ TEST_CASE("constructors") ...@@ -1148,11 +1181,15 @@ TEST_CASE("constructors")
json j = 17; json j = 17;
CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
CHECK_THROWS_NAME(json(j.end(), j.end()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(json(j.begin(), j.begin()), std::out_of_range, "iterators out of range");
} }
{ {
json j = 17; json j = 17;
CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
CHECK_THROWS_NAME(json(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(json(j.cbegin(), j.cbegin()), std::out_of_range, "iterators out of range");
} }
} }
...@@ -1162,11 +1199,15 @@ TEST_CASE("constructors") ...@@ -1162,11 +1199,15 @@ TEST_CASE("constructors")
json j = 23.42; json j = 23.42;
CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(json(j.end(), j.end()), std::out_of_range);
CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(json(j.begin(), j.begin()), std::out_of_range);
CHECK_THROWS_NAME(json(j.end(), j.end()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(json(j.begin(), j.begin()), std::out_of_range, "iterators out of range");
} }
{ {
json j = 23.42; json j = 23.42;
CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(json(j.cend(), j.cend()), std::out_of_range);
CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(json(j.cbegin(), j.cbegin()), std::out_of_range);
CHECK_THROWS_NAME(json(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(json(j.cbegin(), j.cbegin()), std::out_of_range, "iterators out of range");
} }
} }
} }
...@@ -1645,6 +1686,19 @@ TEST_CASE("value conversion") ...@@ -1645,6 +1686,19 @@ TEST_CASE("value conversion")
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::object_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::boolean).get<json::object_t>(), std::logic_error);
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::object_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::object_t>(), std::logic_error);
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::object_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_float).get<json::object_t>(), std::logic_error);
CHECK_THROWS_NAME(json(json::value_t::null).get<json::object_t>(), std::logic_error,
"type must be object, but is null");
CHECK_THROWS_NAME(json(json::value_t::array).get<json::object_t>(), std::logic_error,
"type must be object, but is array");
CHECK_THROWS_NAME(json(json::value_t::string).get<json::object_t>(), std::logic_error,
"type must be object, but is string");
CHECK_THROWS_NAME(json(json::value_t::boolean).get<json::object_t>(), std::logic_error,
"type must be object, but is boolean");
CHECK_THROWS_NAME(json(json::value_t::number_integer).get<json::object_t>(), std::logic_error,
"type must be object, but is number");
CHECK_THROWS_NAME(json(json::value_t::number_float).get<json::object_t>(), std::logic_error,
"type must be object, but is number");
} }
} }
...@@ -1727,6 +1781,19 @@ TEST_CASE("value conversion") ...@@ -1727,6 +1781,19 @@ TEST_CASE("value conversion")
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::array_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::boolean).get<json::array_t>(), std::logic_error);
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::array_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::array_t>(), std::logic_error);
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::array_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_float).get<json::array_t>(), std::logic_error);
CHECK_THROWS_NAME(json(json::value_t::null).get<json::array_t>(), std::logic_error,
"type must be array, but is null");
CHECK_THROWS_NAME(json(json::value_t::object).get<json::array_t>(), std::logic_error,
"type must be array, but is object");
CHECK_THROWS_NAME(json(json::value_t::string).get<json::array_t>(), std::logic_error,
"type must be array, but is string");
CHECK_THROWS_NAME(json(json::value_t::boolean).get<json::array_t>(), std::logic_error,
"type must be array, but is boolean");
CHECK_THROWS_NAME(json(json::value_t::number_integer).get<json::array_t>(), std::logic_error,
"type must be array, but is number");
CHECK_THROWS_NAME(json(json::value_t::number_float).get<json::array_t>(), std::logic_error,
"type must be array, but is number");
} }
} }
...@@ -1791,6 +1858,19 @@ TEST_CASE("value conversion") ...@@ -1791,6 +1858,19 @@ TEST_CASE("value conversion")
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::string_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::boolean).get<json::string_t>(), std::logic_error);
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::string_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::string_t>(), std::logic_error);
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::string_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_float).get<json::string_t>(), std::logic_error);
CHECK_THROWS_NAME(json(json::value_t::null).get<json::string_t>(), std::logic_error,
"type must be string, but is null");
CHECK_THROWS_NAME(json(json::value_t::object).get<json::string_t>(), std::logic_error,
"type must be string, but is object");
CHECK_THROWS_NAME(json(json::value_t::array).get<json::string_t>(), std::logic_error,
"type must be string, but is array");
CHECK_THROWS_NAME(json(json::value_t::boolean).get<json::string_t>(), std::logic_error,
"type must be string, but is boolean");
CHECK_THROWS_NAME(json(json::value_t::number_integer).get<json::string_t>(), std::logic_error,
"type must be string, but is number");
CHECK_THROWS_NAME(json(json::value_t::number_float).get<json::string_t>(), std::logic_error,
"type must be string, but is number");
} }
} }
...@@ -1837,6 +1917,19 @@ TEST_CASE("value conversion") ...@@ -1837,6 +1917,19 @@ TEST_CASE("value conversion")
CHECK_THROWS_AS(json(json::value_t::string).get<json::boolean_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::string).get<json::boolean_t>(), std::logic_error);
CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::boolean_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_integer).get<json::boolean_t>(), std::logic_error);
CHECK_THROWS_AS(json(json::value_t::number_float).get<json::boolean_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::number_float).get<json::boolean_t>(), std::logic_error);
CHECK_THROWS_NAME(json(json::value_t::null).get<json::boolean_t>(), std::logic_error,
"type must be boolean, but is null");
CHECK_THROWS_NAME(json(json::value_t::object).get<json::boolean_t>(), std::logic_error,
"type must be boolean, but is object");
CHECK_THROWS_NAME(json(json::value_t::array).get<json::boolean_t>(), std::logic_error,
"type must be boolean, but is array");
CHECK_THROWS_NAME(json(json::value_t::string).get<json::boolean_t>(), std::logic_error,
"type must be boolean, but is string");
CHECK_THROWS_NAME(json(json::value_t::number_integer).get<json::boolean_t>(), std::logic_error,
"type must be boolean, but is number");
CHECK_THROWS_NAME(json(json::value_t::number_float).get<json::boolean_t>(), std::logic_error,
"type must be boolean, but is number");
} }
} }
...@@ -2068,6 +2161,18 @@ TEST_CASE("value conversion") ...@@ -2068,6 +2161,18 @@ TEST_CASE("value conversion")
CHECK_THROWS_AS(json(json::value_t::array).get<json::number_integer_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::array).get<json::number_integer_t>(), std::logic_error);
CHECK_THROWS_AS(json(json::value_t::string).get<json::number_integer_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::string).get<json::number_integer_t>(), std::logic_error);
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_integer_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_integer_t>(), std::logic_error);
CHECK_THROWS_NAME(json(json::value_t::null).get<json::number_integer_t>(), std::logic_error,
"type must be number, but is null");
CHECK_THROWS_NAME(json(json::value_t::object).get<json::number_integer_t>(), std::logic_error,
"type must be number, but is object");
CHECK_THROWS_NAME(json(json::value_t::array).get<json::number_integer_t>(), std::logic_error,
"type must be number, but is array");
CHECK_THROWS_NAME(json(json::value_t::string).get<json::number_integer_t>(), std::logic_error,
"type must be number, but is string");
CHECK_THROWS_NAME(json(json::value_t::boolean).get<json::number_integer_t>(), std::logic_error,
"type must be number, but is boolean");
CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_integer_t>()); CHECK_NOTHROW(json(json::value_t::number_float).get<json::number_integer_t>());
} }
} }
...@@ -2306,6 +2411,18 @@ TEST_CASE("value conversion") ...@@ -2306,6 +2411,18 @@ TEST_CASE("value conversion")
CHECK_THROWS_AS(json(json::value_t::array).get<json::number_float_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::array).get<json::number_float_t>(), std::logic_error);
CHECK_THROWS_AS(json(json::value_t::string).get<json::number_float_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::string).get<json::number_float_t>(), std::logic_error);
CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_float_t>(), std::logic_error); CHECK_THROWS_AS(json(json::value_t::boolean).get<json::number_float_t>(), std::logic_error);
CHECK_THROWS_NAME(json(json::value_t::null).get<json::number_float_t>(), std::logic_error,
"type must be number, but is null");
CHECK_THROWS_NAME(json(json::value_t::object).get<json::number_float_t>(), std::logic_error,
"type must be number, but is object");
CHECK_THROWS_NAME(json(json::value_t::array).get<json::number_float_t>(), std::logic_error,
"type must be number, but is array");
CHECK_THROWS_NAME(json(json::value_t::string).get<json::number_float_t>(), std::logic_error,
"type must be number, but is string");
CHECK_THROWS_NAME(json(json::value_t::boolean).get<json::number_float_t>(), std::logic_error,
"type must be number, but is boolean");
CHECK_NOTHROW(json(json::value_t::number_integer).get<json::number_float_t>()); CHECK_NOTHROW(json(json::value_t::number_integer).get<json::number_float_t>());
} }
} }
...@@ -2381,6 +2498,8 @@ TEST_CASE("value conversion") ...@@ -2381,6 +2498,8 @@ TEST_CASE("value conversion")
SECTION("exception in case of a non-object type") SECTION("exception in case of a non-object type")
{ {
CHECK_THROWS_AS((json().get<std::map<std::string, int>>()), std::logic_error); CHECK_THROWS_AS((json().get<std::map<std::string, int>>()), std::logic_error);
CHECK_THROWS_NAME((json().get<std::map<std::string, int>>()), std::logic_error,
"type must be object, but is null");
} }
} }
...@@ -2445,6 +2564,15 @@ TEST_CASE("value conversion") ...@@ -2445,6 +2564,15 @@ TEST_CASE("value conversion")
CHECK_THROWS_AS((json().get<std::vector<int>>()), std::logic_error); CHECK_THROWS_AS((json().get<std::vector<int>>()), std::logic_error);
CHECK_THROWS_AS((json().get<std::vector<json>>()), std::logic_error); CHECK_THROWS_AS((json().get<std::vector<json>>()), std::logic_error);
CHECK_THROWS_AS((json().get<std::list<json>>()), std::logic_error); CHECK_THROWS_AS((json().get<std::list<json>>()), std::logic_error);
CHECK_THROWS_NAME((json().get<std::list<int>>()), std::logic_error,
"type must be array, but is null");
CHECK_THROWS_NAME((json().get<std::vector<int>>()), std::logic_error,
"type must be array, but is null");
CHECK_THROWS_NAME((json().get<std::vector<json>>()), std::logic_error,
"type must be array, but is null");
CHECK_THROWS_NAME((json().get<std::list<json>>()), std::logic_error,
"type must be array, but is null");
} }
} }
} }
...@@ -2663,15 +2791,8 @@ TEST_CASE("element access") ...@@ -2663,15 +2791,8 @@ TEST_CASE("element access")
CHECK_THROWS_AS(j.at(7), std::out_of_range); CHECK_THROWS_AS(j.at(7), std::out_of_range);
CHECK_THROWS_AS(j_const.at(7), std::out_of_range); CHECK_THROWS_AS(j_const.at(7), std::out_of_range);
// exception name CHECK_THROWS_NAME(j.at(7), std::out_of_range, "array index 7 is out of range");
try CHECK_THROWS_NAME(j_const.at(7), std::out_of_range, "array index 7 is out of range");
{
j.at(7);
}
catch (std::out_of_range& e)
{
CHECK(std::string(e.what()) == "array index 7 is out of range");
}
} }
SECTION("access on non-array type") SECTION("access on non-array type")
...@@ -2683,15 +2804,8 @@ TEST_CASE("element access") ...@@ -2683,15 +2804,8 @@ TEST_CASE("element access")
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
// exception name CHECK_THROWS_NAME(j_nonarray.at(0), std::domain_error, "cannot use at() with null");
try CHECK_THROWS_NAME(j_nonarray_const.at(0), std::domain_error, "cannot use at() with null");
{
j_nonarray.at(0);
}
catch (std::domain_error& e)
{
CHECK(std::string(e.what()) == "cannot use at() with null");
}
} }
SECTION("boolean") SECTION("boolean")
...@@ -2701,15 +2815,8 @@ TEST_CASE("element access") ...@@ -2701,15 +2815,8 @@ TEST_CASE("element access")
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
// exception name CHECK_THROWS_NAME(j_nonarray.at(0), std::domain_error, "cannot use at() with boolean");
try CHECK_THROWS_NAME(j_nonarray_const.at(0), std::domain_error, "cannot use at() with boolean");
{
j_nonarray.at(0);
}
catch (std::domain_error& e)
{
CHECK(std::string(e.what()) == "cannot use at() with boolean");
}
} }
SECTION("string") SECTION("string")
...@@ -2719,15 +2826,8 @@ TEST_CASE("element access") ...@@ -2719,15 +2826,8 @@ TEST_CASE("element access")
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
// exception name CHECK_THROWS_NAME(j_nonarray.at(0), std::domain_error, "cannot use at() with string");
try CHECK_THROWS_NAME(j_nonarray_const.at(0), std::domain_error, "cannot use at() with string");
{
j_nonarray.at(0);
}
catch (std::domain_error& e)
{
CHECK(std::string(e.what()) == "cannot use at() with string");
}
} }
SECTION("object") SECTION("object")
...@@ -2737,15 +2837,8 @@ TEST_CASE("element access") ...@@ -2737,15 +2837,8 @@ TEST_CASE("element access")
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
// exception name CHECK_THROWS_NAME(j_nonarray.at(0), std::domain_error, "cannot use at() with object");
try CHECK_THROWS_NAME(j_nonarray_const.at(0), std::domain_error, "cannot use at() with object");
{
j_nonarray.at(0);
}
catch (std::domain_error& e)
{
CHECK(std::string(e.what()) == "cannot use at() with object");
}
} }
SECTION("number (integer)") SECTION("number (integer)")
...@@ -2755,15 +2848,8 @@ TEST_CASE("element access") ...@@ -2755,15 +2848,8 @@ TEST_CASE("element access")
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
// exception name CHECK_THROWS_NAME(j_nonarray.at(0), std::domain_error, "cannot use at() with number");
try CHECK_THROWS_NAME(j_nonarray_const.at(0), std::domain_error, "cannot use at() with number");
{
j_nonarray.at(0);
}
catch (std::domain_error& e)
{
CHECK(std::string(e.what()) == "cannot use at() with number");
}
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
...@@ -2773,15 +2859,8 @@ TEST_CASE("element access") ...@@ -2773,15 +2859,8 @@ TEST_CASE("element access")
CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray.at(0), std::domain_error);
CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error); CHECK_THROWS_AS(j_nonarray_const.at(0), std::domain_error);
// exception name CHECK_THROWS_NAME(j_nonarray.at(0), std::domain_error, "cannot use at() with number");
try CHECK_THROWS_NAME(j_nonarray_const.at(0), std::domain_error, "cannot use at() with number");
{
j_nonarray.at(0);
}
catch (std::domain_error& e)
{
CHECK(std::string(e.what()) == "cannot use at() with number");
}
} }
} }
} }
...@@ -2825,6 +2904,7 @@ TEST_CASE("element access") ...@@ -2825,6 +2904,7 @@ TEST_CASE("element access")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_NOTHROW(j_nonarray[0]); CHECK_NOTHROW(j_nonarray[0]);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
CHECK_THROWS_NAME(j_nonarray_const[0], std::domain_error, "cannot use operator[] with null");
} }
SECTION("implicit transformation to properly filled array") SECTION("implicit transformation to properly filled array")
...@@ -2841,6 +2921,8 @@ TEST_CASE("element access") ...@@ -2841,6 +2921,8 @@ TEST_CASE("element access")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], std::domain_error); CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
CHECK_THROWS_NAME(j_nonarray[0], std::domain_error, "cannot use operator[] with boolean");
CHECK_THROWS_NAME(j_nonarray_const[0], std::domain_error, "cannot use operator[] with boolean");
} }
SECTION("string") SECTION("string")
...@@ -2849,6 +2931,8 @@ TEST_CASE("element access") ...@@ -2849,6 +2931,8 @@ TEST_CASE("element access")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], std::domain_error); CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
CHECK_THROWS_NAME(j_nonarray[0], std::domain_error, "cannot use operator[] with string");
CHECK_THROWS_NAME(j_nonarray_const[0], std::domain_error, "cannot use operator[] with string");
} }
SECTION("object") SECTION("object")
...@@ -2857,6 +2941,8 @@ TEST_CASE("element access") ...@@ -2857,6 +2941,8 @@ TEST_CASE("element access")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], std::domain_error); CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
CHECK_THROWS_NAME(j_nonarray[0], std::domain_error, "cannot use operator[] with object");
CHECK_THROWS_NAME(j_nonarray_const[0], std::domain_error, "cannot use operator[] with object");
} }
SECTION("number (integer)") SECTION("number (integer)")
...@@ -2865,6 +2951,8 @@ TEST_CASE("element access") ...@@ -2865,6 +2951,8 @@ TEST_CASE("element access")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], std::domain_error); CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
CHECK_THROWS_NAME(j_nonarray[0], std::domain_error, "cannot use operator[] with number");
CHECK_THROWS_NAME(j_nonarray_const[0], std::domain_error, "cannot use operator[] with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
...@@ -2873,6 +2961,8 @@ TEST_CASE("element access") ...@@ -2873,6 +2961,8 @@ TEST_CASE("element access")
const json j_nonarray_const(j_nonarray); const json j_nonarray_const(j_nonarray);
CHECK_THROWS_AS(j_nonarray[0], std::domain_error); CHECK_THROWS_AS(j_nonarray[0], std::domain_error);
CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error); CHECK_THROWS_AS(j_nonarray_const[0], std::domain_error);
CHECK_THROWS_NAME(j_nonarray[0], std::domain_error, "cannot use operator[] with number");
CHECK_THROWS_NAME(j_nonarray_const[0], std::domain_error, "cannot use operator[] with number");
} }
} }
} }
...@@ -2919,6 +3009,7 @@ TEST_CASE("element access") ...@@ -2919,6 +3009,7 @@ TEST_CASE("element access")
{ {
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
CHECK_THROWS_AS(jarray.erase(7), std::out_of_range); CHECK_THROWS_AS(jarray.erase(7), std::out_of_range);
CHECK_THROWS_NAME(jarray.erase(7), std::out_of_range, "index out of range");
} }
} }
...@@ -3015,6 +3106,15 @@ TEST_CASE("element access") ...@@ -3015,6 +3106,15 @@ TEST_CASE("element access")
CHECK_THROWS_AS(jarray.erase(jarray.begin(), jarray2.end()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray.begin(), jarray2.end()), std::domain_error);
CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray.end()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray.end()), std::domain_error);
CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray2.end()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray2.begin(), jarray2.end()), std::domain_error);
CHECK_THROWS_NAME(jarray.erase(jarray2.begin()), std::domain_error,
"iterator does not fit current value");
CHECK_THROWS_NAME(jarray.erase(jarray.begin(), jarray2.end()), std::domain_error,
"iterators do not fit current value");
CHECK_THROWS_NAME(jarray.erase(jarray2.begin(), jarray.end()), std::domain_error,
"iterators do not fit current value");
CHECK_THROWS_NAME(jarray.erase(jarray2.begin(), jarray2.end()), std::domain_error,
"iterators do not fit current value");
} }
{ {
json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}; json jarray = {1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
...@@ -3023,6 +3123,15 @@ TEST_CASE("element access") ...@@ -3023,6 +3123,15 @@ TEST_CASE("element access")
CHECK_THROWS_AS(jarray.erase(jarray.cbegin(), jarray2.cend()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray.cbegin(), jarray2.cend()), std::domain_error);
CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray.cend()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray.cend()), std::domain_error);
CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray2.cend()), std::domain_error); CHECK_THROWS_AS(jarray.erase(jarray2.cbegin(), jarray2.cend()), std::domain_error);
CHECK_THROWS_NAME(jarray.erase(jarray2.cbegin()), std::domain_error,
"iterator does not fit current value");
CHECK_THROWS_NAME(jarray.erase(jarray.cbegin(), jarray2.cend()), std::domain_error,
"iterators do not fit current value");
CHECK_THROWS_NAME(jarray.erase(jarray2.cbegin(), jarray.cend()), std::domain_error,
"iterators do not fit current value");
CHECK_THROWS_NAME(jarray.erase(jarray2.cbegin(), jarray2.cend()), std::domain_error,
"iterators do not fit current value");
} }
} }
} }
...@@ -3033,36 +3142,42 @@ TEST_CASE("element access") ...@@ -3033,36 +3142,42 @@ TEST_CASE("element access")
{ {
json j_nonobject(json::value_t::null); json j_nonobject(json::value_t::null);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.erase(0), std::domain_error, "cannot use erase() with null");
} }
SECTION("boolean") SECTION("boolean")
{ {
json j_nonobject(json::value_t::boolean); json j_nonobject(json::value_t::boolean);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.erase(0), std::domain_error, "cannot use erase() with boolean");
} }
SECTION("string") SECTION("string")
{ {
json j_nonobject(json::value_t::string); json j_nonobject(json::value_t::string);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.erase(0), std::domain_error, "cannot use erase() with string");
} }
SECTION("object") SECTION("object")
{ {
json j_nonobject(json::value_t::object); json j_nonobject(json::value_t::object);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.erase(0), std::domain_error, "cannot use erase() with object");
} }
SECTION("number (integer)") SECTION("number (integer)")
{ {
json j_nonobject(json::value_t::number_integer); json j_nonobject(json::value_t::number_integer);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.erase(0), std::domain_error, "cannot use erase() with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
{ {
json j_nonobject(json::value_t::number_float); json j_nonobject(json::value_t::number_float);
CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase(0), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.erase(0), std::domain_error, "cannot use erase() with number");
} }
} }
} }
...@@ -3098,16 +3213,8 @@ TEST_CASE("element access") ...@@ -3098,16 +3213,8 @@ TEST_CASE("element access")
{ {
CHECK_THROWS_AS(j.at("foo"), std::out_of_range); CHECK_THROWS_AS(j.at("foo"), std::out_of_range);
CHECK_THROWS_AS(j_const.at("foo"), std::out_of_range); CHECK_THROWS_AS(j_const.at("foo"), std::out_of_range);
CHECK_THROWS_NAME(j.at("foo"), std::out_of_range, "key 'foo' not found");
// exception name CHECK_THROWS_NAME(j_const.at("foo"), std::out_of_range, "key 'foo' not found");
try
{
j.at("foo");
}
catch (std::out_of_range& e)
{
CHECK(std::string(e.what()) == "key 'foo' not found");
}
} }
SECTION("access on non-object type") SECTION("access on non-object type")
...@@ -3118,16 +3225,8 @@ TEST_CASE("element access") ...@@ -3118,16 +3225,8 @@ TEST_CASE("element access")
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.at("foo"), std::domain_error, "cannot use at() with null");
// exception name CHECK_THROWS_NAME(j_nonobject_const.at("foo"), std::domain_error, "cannot use at() with null");
try
{
j_nonobject.at("foo");
}
catch (std::domain_error& e)
{
CHECK(std::string(e.what()) == "cannot use at() with null");
}
} }
SECTION("boolean") SECTION("boolean")
...@@ -3136,16 +3235,8 @@ TEST_CASE("element access") ...@@ -3136,16 +3235,8 @@ TEST_CASE("element access")
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.at("foo"), std::domain_error, "cannot use at() with boolean");
// exception name CHECK_THROWS_NAME(j_nonobject_const.at("foo"), std::domain_error, "cannot use at() with boolean");
try
{
j_nonobject.at("foo");
}
catch (std::domain_error& e)
{
CHECK(std::string(e.what()) == "cannot use at() with boolean");
}
} }
SECTION("string") SECTION("string")
...@@ -3154,16 +3245,8 @@ TEST_CASE("element access") ...@@ -3154,16 +3245,8 @@ TEST_CASE("element access")
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.at("foo"), std::domain_error, "cannot use at() with string");
// exception name CHECK_THROWS_NAME(j_nonobject_const.at("foo"), std::domain_error, "cannot use at() with string");
try
{
j_nonobject.at("foo");
}
catch (std::domain_error& e)
{
CHECK(std::string(e.what()) == "cannot use at() with string");
}
} }
SECTION("array") SECTION("array")
...@@ -3172,16 +3255,8 @@ TEST_CASE("element access") ...@@ -3172,16 +3255,8 @@ TEST_CASE("element access")
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.at("foo"), std::domain_error, "cannot use at() with array");
// exception name CHECK_THROWS_NAME(j_nonobject_const.at("foo"), std::domain_error, "cannot use at() with array");
try
{
j_nonobject.at("foo");
}
catch (std::domain_error& e)
{
CHECK(std::string(e.what()) == "cannot use at() with array");
}
} }
SECTION("number (integer)") SECTION("number (integer)")
...@@ -3190,16 +3265,8 @@ TEST_CASE("element access") ...@@ -3190,16 +3265,8 @@ TEST_CASE("element access")
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.at("foo"), std::domain_error, "cannot use at() with number");
// exception name CHECK_THROWS_NAME(j_nonobject_const.at("foo"), std::domain_error, "cannot use at() with number");
try
{
j_nonobject.at("foo");
}
catch (std::domain_error& e)
{
CHECK(std::string(e.what()) == "cannot use at() with number");
}
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
...@@ -3208,16 +3275,8 @@ TEST_CASE("element access") ...@@ -3208,16 +3275,8 @@ TEST_CASE("element access")
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.at("foo"), std::domain_error);
CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.at("foo"), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.at("foo"), std::domain_error, "cannot use at() with number");
// exception name CHECK_THROWS_NAME(j_nonobject_const.at("foo"), std::domain_error, "cannot use at() with number");
try
{
j_nonobject.at("foo");
}
catch (std::domain_error& e)
{
CHECK(std::string(e.what()) == "cannot use at() with number");
}
} }
} }
} }
...@@ -3273,6 +3332,9 @@ TEST_CASE("element access") ...@@ -3273,6 +3332,9 @@ TEST_CASE("element access")
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.value("foo", 1), std::domain_error, "cannot use value() with null");
CHECK_THROWS_NAME(j_nonobject_const.value("foo", 1), std::domain_error,
"cannot use value() with null");
} }
SECTION("boolean") SECTION("boolean")
...@@ -3281,6 +3343,10 @@ TEST_CASE("element access") ...@@ -3281,6 +3343,10 @@ TEST_CASE("element access")
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.value("foo", 1), std::domain_error,
"cannot use value() with boolean");
CHECK_THROWS_NAME(j_nonobject_const.value("foo", 1), std::domain_error,
"cannot use value() with boolean");
} }
SECTION("string") SECTION("string")
...@@ -3289,6 +3355,9 @@ TEST_CASE("element access") ...@@ -3289,6 +3355,9 @@ TEST_CASE("element access")
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.value("foo", 1), std::domain_error, "cannot use value() with string");
CHECK_THROWS_NAME(j_nonobject_const.value("foo", 1), std::domain_error,
"cannot use value() with string");
} }
SECTION("array") SECTION("array")
...@@ -3297,6 +3366,9 @@ TEST_CASE("element access") ...@@ -3297,6 +3366,9 @@ TEST_CASE("element access")
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.value("foo", 1), std::domain_error, "cannot use value() with array");
CHECK_THROWS_NAME(j_nonobject_const.value("foo", 1), std::domain_error,
"cannot use value() with array");
} }
SECTION("number (integer)") SECTION("number (integer)")
...@@ -3305,6 +3377,9 @@ TEST_CASE("element access") ...@@ -3305,6 +3377,9 @@ TEST_CASE("element access")
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.value("foo", 1), std::domain_error, "cannot use value() with number");
CHECK_THROWS_NAME(j_nonobject_const.value("foo", 1), std::domain_error,
"cannot use value() with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
...@@ -3313,6 +3388,9 @@ TEST_CASE("element access") ...@@ -3313,6 +3388,9 @@ TEST_CASE("element access")
const json j_nonobject_const(j_nonobject); const json j_nonobject_const(j_nonobject);
CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject.value("foo", 1), std::domain_error);
CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error); CHECK_THROWS_AS(j_nonobject_const.value("foo", 1), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.value("foo", 1), std::domain_error, "cannot use value() with number");
CHECK_THROWS_NAME(j_nonobject_const.value("foo", 1), std::domain_error,
"cannot use value() with number");
} }
} }
} }
...@@ -3385,6 +3463,9 @@ TEST_CASE("element access") ...@@ -3385,6 +3463,9 @@ TEST_CASE("element access")
CHECK_NOTHROW(j_nonobject2[json::object_t::key_type("foo")]); CHECK_NOTHROW(j_nonobject2[json::object_t::key_type("foo")]);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
CHECK_THROWS_NAME(j_const_nonobject["foo"], std::domain_error, "cannot use operator[] with null");
CHECK_THROWS_NAME(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error,
"cannot use operator[] with null");
} }
SECTION("boolean") SECTION("boolean")
...@@ -3395,6 +3476,13 @@ TEST_CASE("element access") ...@@ -3395,6 +3476,13 @@ TEST_CASE("element access")
CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
CHECK_THROWS_NAME(j_nonobject["foo"], std::domain_error, "cannot use operator[] with boolean");
CHECK_THROWS_NAME(j_nonobject[json::object_t::key_type("foo")], std::domain_error,
"cannot use operator[] with boolean");
CHECK_THROWS_NAME(j_const_nonobject["foo"], std::domain_error,
"cannot use operator[] with boolean");
CHECK_THROWS_NAME(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error,
"cannot use operator[] with boolean");
} }
SECTION("string") SECTION("string")
...@@ -3405,6 +3493,12 @@ TEST_CASE("element access") ...@@ -3405,6 +3493,12 @@ TEST_CASE("element access")
CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
CHECK_THROWS_NAME(j_nonobject["foo"], std::domain_error, "cannot use operator[] with string");
CHECK_THROWS_NAME(j_nonobject[json::object_t::key_type("foo")], std::domain_error,
"cannot use operator[] with string");
CHECK_THROWS_NAME(j_const_nonobject["foo"], std::domain_error, "cannot use operator[] with string");
CHECK_THROWS_NAME(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error,
"cannot use operator[] with string");
} }
SECTION("array") SECTION("array")
...@@ -3415,6 +3509,12 @@ TEST_CASE("element access") ...@@ -3415,6 +3509,12 @@ TEST_CASE("element access")
CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
CHECK_THROWS_NAME(j_nonobject["foo"], std::domain_error, "cannot use operator[] with array");
CHECK_THROWS_NAME(j_nonobject[json::object_t::key_type("foo")], std::domain_error,
"cannot use operator[] with array");
CHECK_THROWS_NAME(j_const_nonobject["foo"], std::domain_error, "cannot use operator[] with array");
CHECK_THROWS_NAME(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error,
"cannot use operator[] with array");
} }
SECTION("number (integer)") SECTION("number (integer)")
...@@ -3425,6 +3525,12 @@ TEST_CASE("element access") ...@@ -3425,6 +3525,12 @@ TEST_CASE("element access")
CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
CHECK_THROWS_NAME(j_nonobject["foo"], std::domain_error, "cannot use operator[] with number");
CHECK_THROWS_NAME(j_nonobject[json::object_t::key_type("foo")], std::domain_error,
"cannot use operator[] with number");
CHECK_THROWS_NAME(j_const_nonobject["foo"], std::domain_error, "cannot use operator[] with number");
CHECK_THROWS_NAME(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error,
"cannot use operator[] with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
...@@ -3435,6 +3541,12 @@ TEST_CASE("element access") ...@@ -3435,6 +3541,12 @@ TEST_CASE("element access")
CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_nonobject[json::object_t::key_type("foo")], std::domain_error);
CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error); CHECK_THROWS_AS(j_const_nonobject["foo"], std::domain_error);
CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error); CHECK_THROWS_AS(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error);
CHECK_THROWS_NAME(j_nonobject["foo"], std::domain_error, "cannot use operator[] with number");
CHECK_THROWS_NAME(j_nonobject[json::object_t::key_type("foo")], std::domain_error,
"cannot use operator[] with number");
CHECK_THROWS_NAME(j_const_nonobject["foo"], std::domain_error, "cannot use operator[] with number");
CHECK_THROWS_NAME(j_const_nonobject[json::object_t::key_type("foo")], std::domain_error,
"cannot use operator[] with number");
} }
} }
} }
...@@ -3572,6 +3684,14 @@ TEST_CASE("element access") ...@@ -3572,6 +3684,14 @@ TEST_CASE("element access")
CHECK_THROWS_AS(jobject.erase(jobject.begin(), jobject2.end()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject.begin(), jobject2.end()), std::domain_error);
CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject.end()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject.end()), std::domain_error);
CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject2.end()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject2.begin(), jobject2.end()), std::domain_error);
CHECK_THROWS_NAME(jobject.erase(jobject2.begin()), std::domain_error,
"iterator does not fit current value");
CHECK_THROWS_NAME(jobject.erase(jobject.begin(), jobject2.end()), std::domain_error,
"iterators do not fit current value");
CHECK_THROWS_NAME(jobject.erase(jobject2.begin(), jobject.end()), std::domain_error,
"iterators do not fit current value");
CHECK_THROWS_NAME(jobject.erase(jobject2.begin(), jobject2.end()), std::domain_error,
"iterators do not fit current value");
} }
{ {
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}, {"d", false}, {"e", true}}; json jobject = {{"a", "a"}, {"b", 1}, {"c", 17}, {"d", false}, {"e", true}};
...@@ -3580,6 +3700,14 @@ TEST_CASE("element access") ...@@ -3580,6 +3700,14 @@ TEST_CASE("element access")
CHECK_THROWS_AS(jobject.erase(jobject.cbegin(), jobject2.cend()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject.cbegin(), jobject2.cend()), std::domain_error);
CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject.cend()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject.cend()), std::domain_error);
CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()), std::domain_error); CHECK_THROWS_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()), std::domain_error);
CHECK_THROWS_NAME(jobject.erase(jobject2.cbegin()), std::domain_error,
"iterator does not fit current value");
CHECK_THROWS_NAME(jobject.erase(jobject.cbegin(), jobject2.cend()), std::domain_error,
"iterators do not fit current value");
CHECK_THROWS_NAME(jobject.erase(jobject2.cbegin(), jobject.cend()), std::domain_error,
"iterators do not fit current value");
CHECK_THROWS_NAME(jobject.erase(jobject2.cbegin(), jobject2.cend()), std::domain_error,
"iterators do not fit current value");
} }
} }
} }
...@@ -3590,36 +3718,42 @@ TEST_CASE("element access") ...@@ -3590,36 +3718,42 @@ TEST_CASE("element access")
{ {
json j_nonobject(json::value_t::null); json j_nonobject(json::value_t::null);
CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.erase("foo"), std::domain_error, "cannot use erase() with null");
} }
SECTION("boolean") SECTION("boolean")
{ {
json j_nonobject(json::value_t::boolean); json j_nonobject(json::value_t::boolean);
CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.erase("foo"), std::domain_error, "cannot use erase() with boolean");
} }
SECTION("string") SECTION("string")
{ {
json j_nonobject(json::value_t::string); json j_nonobject(json::value_t::string);
CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.erase("foo"), std::domain_error, "cannot use erase() with string");
} }
SECTION("array") SECTION("array")
{ {
json j_nonobject(json::value_t::array); json j_nonobject(json::value_t::array);
CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.erase("foo"), std::domain_error, "cannot use erase() with array");
} }
SECTION("number (integer)") SECTION("number (integer)")
{ {
json j_nonobject(json::value_t::number_integer); json j_nonobject(json::value_t::number_integer);
CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.erase("foo"), std::domain_error, "cannot use erase() with number");
} }
SECTION("number (floating-point)") SECTION("number (floating-point)")
{ {
json j_nonobject(json::value_t::number_float); json j_nonobject(json::value_t::number_float);
CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error); CHECK_THROWS_AS(j_nonobject.erase("foo"), std::domain_error);
CHECK_THROWS_NAME(j_nonobject.erase("foo"), std::domain_error, "cannot use erase() with number");
} }
} }
} }
...@@ -3795,11 +3929,15 @@ TEST_CASE("element access") ...@@ -3795,11 +3929,15 @@ TEST_CASE("element access")
json j; json j;
CHECK_THROWS_AS(j.front(), std::out_of_range); CHECK_THROWS_AS(j.front(), std::out_of_range);
CHECK_THROWS_AS(j.back(), std::out_of_range); CHECK_THROWS_AS(j.back(), std::out_of_range);
CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
} }
{ {
const json j{}; const json j{};
CHECK_THROWS_AS(j.front(), std::out_of_range); CHECK_THROWS_AS(j.front(), std::out_of_range);
CHECK_THROWS_AS(j.back(), std::out_of_range); CHECK_THROWS_AS(j.back(), std::out_of_range);
CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
} }
} }
...@@ -3809,11 +3947,15 @@ TEST_CASE("element access") ...@@ -3809,11 +3947,15 @@ TEST_CASE("element access")
json j = "foo"; json j = "foo";
CHECK(j.front() == j); CHECK(j.front() == j);
CHECK(j.back() == j); CHECK(j.back() == j);
CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
} }
{ {
const json j = "bar"; const json j = "bar";
CHECK(j.front() == j); CHECK(j.front() == j);
CHECK(j.back() == j); CHECK(j.back() == j);
CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
} }
} }
...@@ -3823,11 +3965,15 @@ TEST_CASE("element access") ...@@ -3823,11 +3965,15 @@ TEST_CASE("element access")
json j = false; json j = false;
CHECK(j.front() == j); CHECK(j.front() == j);
CHECK(j.back() == j); CHECK(j.back() == j);
CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
} }
{ {
const json j = true; const json j = true;
CHECK(j.front() == j); CHECK(j.front() == j);
CHECK(j.back() == j); CHECK(j.back() == j);
CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
} }
} }
...@@ -3837,11 +3983,15 @@ TEST_CASE("element access") ...@@ -3837,11 +3983,15 @@ TEST_CASE("element access")
json j = 17; json j = 17;
CHECK(j.front() == j); CHECK(j.front() == j);
CHECK(j.back() == j); CHECK(j.back() == j);
CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
} }
{ {
const json j = 17; const json j = 17;
CHECK(j.front() == j); CHECK(j.front() == j);
CHECK(j.back() == j); CHECK(j.back() == j);
CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
} }
} }
...@@ -3851,11 +4001,15 @@ TEST_CASE("element access") ...@@ -3851,11 +4001,15 @@ TEST_CASE("element access")
json j = 23.42; json j = 23.42;
CHECK(j.front() == j); CHECK(j.front() == j);
CHECK(j.back() == j); CHECK(j.back() == j);
CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
} }
{ {
const json j = 23.42; const json j = 23.42;
CHECK(j.front() == j); CHECK(j.front() == j);
CHECK(j.back() == j); CHECK(j.back() == j);
CHECK_THROWS_NAME(j.front(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(j.back(), std::out_of_range, "cannot get value");
} }
} }
} }
...@@ -3867,10 +4021,12 @@ TEST_CASE("element access") ...@@ -3867,10 +4021,12 @@ TEST_CASE("element access")
{ {
json j; json j;
CHECK_THROWS_AS(j.erase(j.begin()), std::domain_error); CHECK_THROWS_AS(j.erase(j.begin()), std::domain_error);
CHECK_THROWS_NAME(j.erase(j.begin()), std::domain_error, "cannot use erase() with null");
} }
{ {
json j; json j;
CHECK_THROWS_AS(j.erase(j.cbegin()), std::domain_error); CHECK_THROWS_AS(j.erase(j.cbegin()), std::domain_error);
CHECK_THROWS_NAME(j.erase(j.begin()), std::domain_error, "cannot use erase() with null");
} }
} }
...@@ -3946,10 +4102,12 @@ TEST_CASE("element access") ...@@ -3946,10 +4102,12 @@ TEST_CASE("element access")
{ {
json j = "foo"; json j = "foo";
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.end()), std::out_of_range, "iterator out of range");
} }
{ {
json j = "bar"; json j = "bar";
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.cend()), std::out_of_range, "iterator out of range");
} }
} }
...@@ -3958,10 +4116,12 @@ TEST_CASE("element access") ...@@ -3958,10 +4116,12 @@ TEST_CASE("element access")
{ {
json j = false; json j = false;
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.end()), std::out_of_range, "iterator out of range");
} }
{ {
json j = true; json j = true;
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.cend()), std::out_of_range, "iterator out of range");
} }
} }
...@@ -3970,10 +4130,12 @@ TEST_CASE("element access") ...@@ -3970,10 +4130,12 @@ TEST_CASE("element access")
{ {
json j = 17; json j = 17;
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.end()), std::out_of_range, "iterator out of range");
} }
{ {
json j = 17; json j = 17;
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.cend()), std::out_of_range, "iterator out of range");
} }
} }
...@@ -3982,10 +4144,12 @@ TEST_CASE("element access") ...@@ -3982,10 +4144,12 @@ TEST_CASE("element access")
{ {
json j = 23.42; json j = 23.42;
CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.end()), std::out_of_range, "iterator out of range");
} }
{ {
json j = 23.42; json j = 23.42;
CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.cend()), std::out_of_range, "iterator out of range");
} }
} }
} }
...@@ -3997,10 +4161,12 @@ TEST_CASE("element access") ...@@ -3997,10 +4161,12 @@ TEST_CASE("element access")
{ {
json j; json j;
CHECK_THROWS_AS(j.erase(j.begin(), j.end()), std::domain_error); CHECK_THROWS_AS(j.erase(j.begin(), j.end()), std::domain_error);
CHECK_THROWS_NAME(j.erase(j.begin(), j.end()), std::domain_error, "cannot use erase() with null");
} }
{ {
json j; json j;
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cend()), std::domain_error); CHECK_THROWS_AS(j.erase(j.cbegin(), j.cend()), std::domain_error);
CHECK_THROWS_NAME(j.erase(j.cbegin(), j.cend()), std::domain_error, "cannot use erase() with null");
} }
} }
...@@ -4077,11 +4243,15 @@ TEST_CASE("element access") ...@@ -4077,11 +4243,15 @@ TEST_CASE("element access")
json j = "foo"; json j = "foo";
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.end(), j.end()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(j.erase(j.begin(), j.begin()), std::out_of_range, "iterators out of range");
} }
{ {
json j = "bar"; json j = "bar";
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(j.erase(j.cbegin(), j.cbegin()), std::out_of_range, "iterators out of range");
} }
} }
...@@ -4091,11 +4261,15 @@ TEST_CASE("element access") ...@@ -4091,11 +4261,15 @@ TEST_CASE("element access")
json j = false; json j = false;
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.end(), j.end()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(j.erase(j.begin(), j.begin()), std::out_of_range, "iterators out of range");
} }
{ {
json j = true; json j = true;
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(j.erase(j.cbegin(), j.cbegin()), std::out_of_range, "iterators out of range");
} }
} }
...@@ -4105,11 +4279,15 @@ TEST_CASE("element access") ...@@ -4105,11 +4279,15 @@ TEST_CASE("element access")
json j = 17; json j = 17;
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.end(), j.end()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(j.erase(j.begin(), j.begin()), std::out_of_range, "iterators out of range");
} }
{ {
json j = 17; json j = 17;
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(j.erase(j.cbegin(), j.cbegin()), std::out_of_range, "iterators out of range");
} }
} }
...@@ -4119,11 +4297,15 @@ TEST_CASE("element access") ...@@ -4119,11 +4297,15 @@ TEST_CASE("element access")
json j = 23.42; json j = 23.42;
CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.end(), j.end()), std::out_of_range);
CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.begin(), j.begin()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.end(), j.end()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(j.erase(j.begin(), j.begin()), std::out_of_range, "iterators out of range");
} }
{ {
json j = 23.42; json j = 23.42;
CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cend(), j.cend()), std::out_of_range);
CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range); CHECK_THROWS_AS(j.erase(j.cbegin(), j.cbegin()), std::out_of_range);
CHECK_THROWS_NAME(j.erase(j.cend(), j.cend()), std::out_of_range, "iterators out of range");
CHECK_THROWS_NAME(j.erase(j.cbegin(), j.cbegin()), std::out_of_range, "iterators out of range");
} }
} }
} }
...@@ -4328,8 +4510,10 @@ TEST_CASE("iterators") ...@@ -4328,8 +4510,10 @@ TEST_CASE("iterators")
auto it = j.begin(); auto it = j.begin();
auto cit = j_const.cbegin(); auto cit = j_const.cbegin();
CHECK_THROWS_AS(it.key(), std::domain_error); CHECK_THROWS_AS(it.key(), std::domain_error);
CHECK_THROWS_NAME(it.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK(it.value() == json(true)); CHECK(it.value() == json(true));
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), std::domain_error);
CHECK_THROWS_NAME(cit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK(cit.value() == json(true)); CHECK(cit.value() == json(true));
auto rit = j.rend(); auto rit = j.rend();
...@@ -4338,6 +4522,10 @@ TEST_CASE("iterators") ...@@ -4338,6 +4522,10 @@ TEST_CASE("iterators")
CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(rit.value(), std::out_of_range);
CHECK_THROWS_AS(crit.key(), std::domain_error); CHECK_THROWS_AS(crit.key(), std::domain_error);
CHECK_THROWS_AS(crit.value(), std::out_of_range); CHECK_THROWS_AS(crit.value(), std::out_of_range);
CHECK_THROWS_NAME(rit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK_THROWS_NAME(rit.value(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(crit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK_THROWS_NAME(crit.value(), std::out_of_range, "cannot get value");
} }
} }
...@@ -4526,8 +4714,10 @@ TEST_CASE("iterators") ...@@ -4526,8 +4714,10 @@ TEST_CASE("iterators")
auto it = j.begin(); auto it = j.begin();
auto cit = j_const.cbegin(); auto cit = j_const.cbegin();
CHECK_THROWS_AS(it.key(), std::domain_error); CHECK_THROWS_AS(it.key(), std::domain_error);
CHECK_THROWS_NAME(it.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK(it.value() == json("hello world")); CHECK(it.value() == json("hello world"));
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), std::domain_error);
CHECK_THROWS_NAME(cit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK(cit.value() == json("hello world")); CHECK(cit.value() == json("hello world"));
auto rit = j.rend(); auto rit = j.rend();
...@@ -4536,6 +4726,10 @@ TEST_CASE("iterators") ...@@ -4536,6 +4726,10 @@ TEST_CASE("iterators")
CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(rit.value(), std::out_of_range);
CHECK_THROWS_AS(crit.key(), std::domain_error); CHECK_THROWS_AS(crit.key(), std::domain_error);
CHECK_THROWS_AS(crit.value(), std::out_of_range); CHECK_THROWS_AS(crit.value(), std::out_of_range);
CHECK_THROWS_NAME(rit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK_THROWS_NAME(rit.value(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(crit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK_THROWS_NAME(crit.value(), std::out_of_range, "cannot get value");
} }
} }
...@@ -4717,8 +4911,10 @@ TEST_CASE("iterators") ...@@ -4717,8 +4911,10 @@ TEST_CASE("iterators")
auto it = j.begin(); auto it = j.begin();
auto cit = j_const.cbegin(); auto cit = j_const.cbegin();
CHECK_THROWS_AS(it.key(), std::domain_error); CHECK_THROWS_AS(it.key(), std::domain_error);
CHECK_THROWS_NAME(it.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK(it.value() == json(1)); CHECK(it.value() == json(1));
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), std::domain_error);
CHECK_THROWS_NAME(cit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK(cit.value() == json(1)); CHECK(cit.value() == json(1));
} }
} }
...@@ -5092,8 +5288,10 @@ TEST_CASE("iterators") ...@@ -5092,8 +5288,10 @@ TEST_CASE("iterators")
auto it = j.begin(); auto it = j.begin();
auto cit = j_const.cbegin(); auto cit = j_const.cbegin();
CHECK_THROWS_AS(it.key(), std::domain_error); CHECK_THROWS_AS(it.key(), std::domain_error);
CHECK_THROWS_NAME(it.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK(it.value() == json(23)); CHECK(it.value() == json(23));
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), std::domain_error);
CHECK_THROWS_NAME(cit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK(cit.value() == json(23)); CHECK(cit.value() == json(23));
auto rit = j.rend(); auto rit = j.rend();
...@@ -5102,6 +5300,10 @@ TEST_CASE("iterators") ...@@ -5102,6 +5300,10 @@ TEST_CASE("iterators")
CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(rit.value(), std::out_of_range);
CHECK_THROWS_AS(crit.key(), std::domain_error); CHECK_THROWS_AS(crit.key(), std::domain_error);
CHECK_THROWS_AS(crit.value(), std::out_of_range); CHECK_THROWS_AS(crit.value(), std::out_of_range);
CHECK_THROWS_NAME(rit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK_THROWS_NAME(rit.value(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(crit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK_THROWS_NAME(crit.value(), std::out_of_range, "cannot get value");
} }
} }
...@@ -5290,8 +5492,10 @@ TEST_CASE("iterators") ...@@ -5290,8 +5492,10 @@ TEST_CASE("iterators")
auto it = j.begin(); auto it = j.begin();
auto cit = j_const.cbegin(); auto cit = j_const.cbegin();
CHECK_THROWS_AS(it.key(), std::domain_error); CHECK_THROWS_AS(it.key(), std::domain_error);
CHECK_THROWS_NAME(it.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK(it.value() == json(23.42)); CHECK(it.value() == json(23.42));
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), std::domain_error);
CHECK_THROWS_NAME(cit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK(cit.value() == json(23.42)); CHECK(cit.value() == json(23.42));
auto rit = j.rend(); auto rit = j.rend();
...@@ -5300,6 +5504,10 @@ TEST_CASE("iterators") ...@@ -5300,6 +5504,10 @@ TEST_CASE("iterators")
CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(rit.value(), std::out_of_range);
CHECK_THROWS_AS(crit.key(), std::domain_error); CHECK_THROWS_AS(crit.key(), std::domain_error);
CHECK_THROWS_AS(crit.value(), std::out_of_range); CHECK_THROWS_AS(crit.value(), std::out_of_range);
CHECK_THROWS_NAME(rit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK_THROWS_NAME(rit.value(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(crit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK_THROWS_NAME(crit.value(), std::out_of_range, "cannot get value");
} }
} }
...@@ -5361,6 +5569,10 @@ TEST_CASE("iterators") ...@@ -5361,6 +5569,10 @@ TEST_CASE("iterators")
CHECK_THROWS_AS(it.value(), std::out_of_range); CHECK_THROWS_AS(it.value(), std::out_of_range);
CHECK_THROWS_AS(cit.key(), std::domain_error); CHECK_THROWS_AS(cit.key(), std::domain_error);
CHECK_THROWS_AS(cit.value(), std::out_of_range); CHECK_THROWS_AS(cit.value(), std::out_of_range);
CHECK_THROWS_NAME(it.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK_THROWS_NAME(it.value(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(cit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK_THROWS_NAME(cit.value(), std::out_of_range, "cannot get value");
auto rit = j.rend(); auto rit = j.rend();
auto crit = j.crend(); auto crit = j.crend();
...@@ -5368,6 +5580,10 @@ TEST_CASE("iterators") ...@@ -5368,6 +5580,10 @@ TEST_CASE("iterators")
CHECK_THROWS_AS(rit.value(), std::out_of_range); CHECK_THROWS_AS(rit.value(), std::out_of_range);
CHECK_THROWS_AS(crit.key(), std::domain_error); CHECK_THROWS_AS(crit.key(), std::domain_error);
CHECK_THROWS_AS(crit.value(), std::out_of_range); CHECK_THROWS_AS(crit.value(), std::out_of_range);
CHECK_THROWS_NAME(rit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK_THROWS_NAME(rit.value(), std::out_of_range, "cannot get value");
CHECK_THROWS_NAME(crit.key(), std::domain_error, "cannot use key() for non-object iterators");
CHECK_THROWS_NAME(crit.value(), std::out_of_range, "cannot get value");
} }
} }
} }
...@@ -5428,6 +5644,14 @@ TEST_CASE("iterators") ...@@ -5428,6 +5644,14 @@ TEST_CASE("iterators")
CHECK_THROWS_AS(it1_c < it2_c, std::domain_error); CHECK_THROWS_AS(it1_c < it2_c, std::domain_error);
CHECK_THROWS_AS(it2_c < it3_c, std::domain_error); CHECK_THROWS_AS(it2_c < it3_c, std::domain_error);
CHECK_THROWS_AS(it1_c < it3_c, std::domain_error); CHECK_THROWS_AS(it1_c < it3_c, std::domain_error);
CHECK_THROWS_NAME(it1 < it1, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1 < it2, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it2 < it3, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1 < it3, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1_c < it1_c, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1_c < it2_c, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it2_c < it3_c, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1_c < it3_c, std::domain_error, "cannot compare order of object iterators");
} }
else else
{ {
...@@ -5454,6 +5678,14 @@ TEST_CASE("iterators") ...@@ -5454,6 +5678,14 @@ TEST_CASE("iterators")
CHECK_THROWS_AS(it1_c <= it2_c, std::domain_error); CHECK_THROWS_AS(it1_c <= it2_c, std::domain_error);
CHECK_THROWS_AS(it2_c <= it3_c, std::domain_error); CHECK_THROWS_AS(it2_c <= it3_c, std::domain_error);
CHECK_THROWS_AS(it1_c <= it3_c, std::domain_error); CHECK_THROWS_AS(it1_c <= it3_c, std::domain_error);
CHECK_THROWS_NAME(it1 <= it1, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1 <= it2, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it2 <= it3, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1 <= it3, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1_c <= it1_c, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1_c <= it2_c, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it2_c <= it3_c, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1_c <= it3_c, std::domain_error, "cannot compare order of object iterators");
} }
else else
{ {
...@@ -5481,6 +5713,14 @@ TEST_CASE("iterators") ...@@ -5481,6 +5713,14 @@ TEST_CASE("iterators")
CHECK_THROWS_AS(it1_c > it2_c, std::domain_error); CHECK_THROWS_AS(it1_c > it2_c, std::domain_error);
CHECK_THROWS_AS(it2_c > it3_c, std::domain_error); CHECK_THROWS_AS(it2_c > it3_c, std::domain_error);
CHECK_THROWS_AS(it1_c > it3_c, std::domain_error); CHECK_THROWS_AS(it1_c > it3_c, std::domain_error);
CHECK_THROWS_NAME(it1 > it1, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1 > it2, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it2 > it3, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1 > it3, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1_c > it1_c, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1_c > it2_c, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it2_c > it3_c, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1_c > it3_c, std::domain_error, "cannot compare order of object iterators");
} }
else else
{ {
...@@ -5508,6 +5748,14 @@ TEST_CASE("iterators") ...@@ -5508,6 +5748,14 @@ TEST_CASE("iterators")
CHECK_THROWS_AS(it1_c >= it2_c, std::domain_error); CHECK_THROWS_AS(it1_c >= it2_c, std::domain_error);
CHECK_THROWS_AS(it2_c >= it3_c, std::domain_error); CHECK_THROWS_AS(it2_c >= it3_c, std::domain_error);
CHECK_THROWS_AS(it1_c >= it3_c, std::domain_error); CHECK_THROWS_AS(it1_c >= it3_c, std::domain_error);
CHECK_THROWS_NAME(it1 >= it1, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1 >= it2, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it2 >= it3, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1 >= it3, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1_c >= it1_c, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1_c >= it2_c, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it2_c >= it3_c, std::domain_error, "cannot compare order of object iterators");
CHECK_THROWS_NAME(it1_c >= it3_c, std::domain_error, "cannot compare order of object iterators");
} }
else else
{ {
...@@ -5533,9 +5781,17 @@ TEST_CASE("iterators") ...@@ -5533,9 +5781,17 @@ TEST_CASE("iterators")
{ {
CHECK_THROWS_AS(j.begin() == k.begin(), std::domain_error); CHECK_THROWS_AS(j.begin() == k.begin(), std::domain_error);
CHECK_THROWS_AS(j.cbegin() == k.cbegin(), std::domain_error); CHECK_THROWS_AS(j.cbegin() == k.cbegin(), std::domain_error);
CHECK_THROWS_NAME(j.begin() == k.begin(), std::domain_error,
"cannot compare iterators of different containers");
CHECK_THROWS_NAME(j.cbegin() == k.cbegin(), std::domain_error,
"cannot compare iterators of different containers");
CHECK_THROWS_AS(j.begin() < k.begin(), std::domain_error); CHECK_THROWS_AS(j.begin() < k.begin(), std::domain_error);
CHECK_THROWS_AS(j.cbegin() < k.cbegin(), std::domain_error); CHECK_THROWS_AS(j.cbegin() < k.cbegin(), std::domain_error);
CHECK_THROWS_NAME(j.begin() < k.begin(), std::domain_error,
"cannot compare iterators of different containers");
CHECK_THROWS_NAME(j.cbegin() < k.cbegin(), std::domain_error,
"cannot compare iterators of different containers");
} }
} }
} }
...@@ -5555,42 +5811,52 @@ TEST_CASE("iterators") ...@@ -5555,42 +5811,52 @@ TEST_CASE("iterators")
{ {
auto it = j_object.begin(); auto it = j_object.begin();
CHECK_THROWS_AS(it += 1, std::domain_error); CHECK_THROWS_AS(it += 1, std::domain_error);
CHECK_THROWS_NAME(it += 1, std::domain_error, "cannot use offsets with object iterators");
} }
{ {
auto it = j_object.cbegin(); auto it = j_object.cbegin();
CHECK_THROWS_AS(it += 1, std::domain_error); CHECK_THROWS_AS(it += 1, std::domain_error);
CHECK_THROWS_NAME(it += 1, std::domain_error, "cannot use offsets with object iterators");
} }
{ {
auto it = j_object.begin(); auto it = j_object.begin();
CHECK_THROWS_AS(it + 1, std::domain_error); CHECK_THROWS_AS(it + 1, std::domain_error);
CHECK_THROWS_NAME(it + 1, std::domain_error, "cannot use offsets with object iterators");
} }
{ {
auto it = j_object.cbegin(); auto it = j_object.cbegin();
CHECK_THROWS_AS(it + 1, std::domain_error); CHECK_THROWS_AS(it + 1, std::domain_error);
CHECK_THROWS_NAME(it + 1, std::domain_error, "cannot use offsets with object iterators");
} }
{ {
auto it = j_object.begin(); auto it = j_object.begin();
CHECK_THROWS_AS(it -= 1, std::domain_error); CHECK_THROWS_AS(it -= 1, std::domain_error);
CHECK_THROWS_NAME(it -= 1, std::domain_error, "cannot use offsets with object iterators");
} }
{ {
auto it = j_object.cbegin(); auto it = j_object.cbegin();
CHECK_THROWS_AS(it -= 1, std::domain_error); CHECK_THROWS_AS(it -= 1, std::domain_error);
CHECK_THROWS_NAME(it -= 1, std::domain_error, "cannot use offsets with object iterators");
} }
{ {
auto it = j_object.begin(); auto it = j_object.begin();
CHECK_THROWS_AS(it - 1, std::domain_error); CHECK_THROWS_AS(it - 1, std::domain_error);
CHECK_THROWS_NAME(it - 1, std::domain_error, "cannot use offsets with object iterators");
} }
{ {
auto it = j_object.cbegin(); auto it = j_object.cbegin();
CHECK_THROWS_AS(it - 1, std::domain_error); CHECK_THROWS_AS(it - 1, std::domain_error);
CHECK_THROWS_NAME(it - 1, std::domain_error, "cannot use offsets with object iterators");
} }
{ {
auto it = j_object.begin(); auto it = j_object.begin();
CHECK_THROWS_AS(it - it, std::domain_error); CHECK_THROWS_AS(it - it, std::domain_error);
CHECK_THROWS_NAME(it - it, std::domain_error, "cannot use offsets with object iterators");
} }
{ {
auto it = j_object.cbegin(); auto it = j_object.cbegin();
CHECK_THROWS_AS(it - it, std::domain_error); CHECK_THROWS_AS(it - it, std::domain_error);
CHECK_THROWS_NAME(it - it, std::domain_error, "cannot use offsets with object iterators");
} }
} }
...@@ -6693,6 +6959,16 @@ TEST_CASE("modifiers") ...@@ -6693,6 +6959,16 @@ TEST_CASE("modifiers")
{ {
json j = 1; json j = 1;
CHECK_THROWS_AS(j.push_back("Hello"), std::domain_error); CHECK_THROWS_AS(j.push_back("Hello"), std::domain_error);
// exception name
try
{
j.push_back("Hello");
}
catch (std::domain_error& e)
{
CHECK(e.what() == std::string("cannot use push_back() with number"));
}
} }
} }
...@@ -6722,6 +6998,16 @@ TEST_CASE("modifiers") ...@@ -6722,6 +6998,16 @@ TEST_CASE("modifiers")
json j = 1; json j = 1;
json k("Hello"); json k("Hello");
CHECK_THROWS_AS(j.push_back(k), std::domain_error); CHECK_THROWS_AS(j.push_back(k), std::domain_error);
// exception name
try
{
j.push_back(k);
}
catch (std::domain_error& e)
{
CHECK(e.what() == std::string("cannot use push_back() with number"));
}
} }
} }
} }
...@@ -6754,6 +7040,16 @@ TEST_CASE("modifiers") ...@@ -6754,6 +7040,16 @@ TEST_CASE("modifiers")
json j = 1; json j = 1;
json k("Hello"); json k("Hello");
CHECK_THROWS_AS(j.push_back(json::object_t::value_type({"one", 1})), std::domain_error); CHECK_THROWS_AS(j.push_back(json::object_t::value_type({"one", 1})), std::domain_error);
// exception name
try
{
j.push_back(k);
}
catch (std::domain_error& e)
{
CHECK(e.what() == std::string("cannot use push_back() with number"));
}
} }
} }
} }
...@@ -6785,6 +7081,16 @@ TEST_CASE("modifiers") ...@@ -6785,6 +7081,16 @@ TEST_CASE("modifiers")
{ {
json j = 1; json j = 1;
CHECK_THROWS_AS(j += "Hello", std::domain_error); CHECK_THROWS_AS(j += "Hello", std::domain_error);
// exception name
try
{
j += "Hello";
}
catch (std::domain_error& e)
{
CHECK(e.what() == std::string("cannot use push_back() with number"));
}
} }
} }
...@@ -6814,6 +7120,16 @@ TEST_CASE("modifiers") ...@@ -6814,6 +7120,16 @@ TEST_CASE("modifiers")
json j = 1; json j = 1;
json k("Hello"); json k("Hello");
CHECK_THROWS_AS(j += k, std::domain_error); CHECK_THROWS_AS(j += k, std::domain_error);
// exception name
try
{
j += k;
}
catch (std::domain_error& e)
{
CHECK(e.what() == std::string("cannot use push_back() with number"));
}
} }
} }
} }
...@@ -6846,6 +7162,17 @@ TEST_CASE("modifiers") ...@@ -6846,6 +7162,17 @@ TEST_CASE("modifiers")
json j = 1; json j = 1;
json k("Hello"); json k("Hello");
CHECK_THROWS_AS(j += json::object_t::value_type({"one", 1}), std::domain_error); CHECK_THROWS_AS(j += json::object_t::value_type({"one", 1}), std::domain_error);
// exception name
try
{
j += json::object_t::value_type({"one", 1});
}
catch (std::domain_error& e)
{
CHECK(e.what() == std::string("cannot use push_back() with number"));
}
} }
} }
} }
...@@ -6982,6 +7309,25 @@ TEST_CASE("modifiers") ...@@ -6982,6 +7309,25 @@ TEST_CASE("modifiers")
CHECK_THROWS_AS(j_array.insert(j_array.end(), j_array.begin(), j_array.end()), std::domain_error); CHECK_THROWS_AS(j_array.insert(j_array.end(), j_array.begin(), j_array.end()), std::domain_error);
CHECK_THROWS_AS(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()), CHECK_THROWS_AS(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),
std::domain_error); std::domain_error);
// exception names
try
{
j_array.insert(j_array.end(), j_array.begin(), j_array.end());
}
catch (std::domain_error& e)
{
CHECK(e.what() == std::string("passed iterators may not belong to container"));
}
try
{
j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end());
}
catch (std::domain_error& e)
{
CHECK(e.what() == std::string("iterators do not fit"));
}
} }
} }
......
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