From b4571360df0294f7e824aced8e13f062f3414493 Mon Sep 17 00:00:00 2001 From: Niels Date: Sun, 21 Aug 2016 12:35:40 +0200 Subject: [PATCH] more on #290 --- README.md | 2 +- .../parse__array__parser_callback_t.cpp | 28 ++++ .../parse__array__parser_callback_t.link | 1 + .../parse__array__parser_callback_t.output | 20 +++ ...contiguouscontainer__parser_callback_t.cpp | 13 ++ ...ontiguouscontainer__parser_callback_t.link | 1 + ...tiguouscontainer__parser_callback_t.output | 6 + ...parse__iteratortype__parser_callback_t.cpp | 13 ++ ...arse__iteratortype__parser_callback_t.link | 1 + ...se__iteratortype__parser_callback_t.output | 6 + .../parse__string__parser_callback_t.cpp | 4 +- .../parse__string__parser_callback_t.link | 2 +- src/json.hpp | 133 ++++++++++++------ src/json.hpp.re2c | 133 ++++++++++++------ test/src/unit-class_parser.cpp | 30 ++-- test/src/unit-deserialization.cpp | 6 + 16 files changed, 298 insertions(+), 101 deletions(-) create mode 100644 doc/examples/parse__array__parser_callback_t.cpp create mode 100644 doc/examples/parse__array__parser_callback_t.link create mode 100644 doc/examples/parse__array__parser_callback_t.output create mode 100644 doc/examples/parse__contiguouscontainer__parser_callback_t.cpp create mode 100644 doc/examples/parse__contiguouscontainer__parser_callback_t.link create mode 100644 doc/examples/parse__contiguouscontainer__parser_callback_t.output create mode 100644 doc/examples/parse__iteratortype__parser_callback_t.cpp create mode 100644 doc/examples/parse__iteratortype__parser_callback_t.link create mode 100644 doc/examples/parse__iteratortype__parser_callback_t.output diff --git a/README.md b/README.md index 3015e860..9893fedd 100644 --- a/README.md +++ b/README.md @@ -511,7 +511,7 @@ To compile and run the tests, you need to execute $ make check =============================================================================== -All tests passed (8905099 assertions in 32 test cases) +All tests passed (8905119 assertions in 32 test cases) ``` For more information, have a look at the file [.travis.yml](https://github.com/nlohmann/json/blob/master/.travis.yml). diff --git a/doc/examples/parse__array__parser_callback_t.cpp b/doc/examples/parse__array__parser_callback_t.cpp new file mode 100644 index 00000000..8e086d20 --- /dev/null +++ b/doc/examples/parse__array__parser_callback_t.cpp @@ -0,0 +1,28 @@ +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text + char text[] = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } + } + )"; + + // parse and serialize JSON + json j_complete = json::parse(text); + std::cout << std::setw(4) << j_complete << "\n\n"; +} diff --git a/doc/examples/parse__array__parser_callback_t.link b/doc/examples/parse__array__parser_callback_t.link new file mode 100644 index 00000000..a1d3cd34 --- /dev/null +++ b/doc/examples/parse__array__parser_callback_t.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/parse__array__parser_callback_t.output b/doc/examples/parse__array__parser_callback_t.output new file mode 100644 index 00000000..62bb8586 --- /dev/null +++ b/doc/examples/parse__array__parser_callback_t.output @@ -0,0 +1,20 @@ +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Thumbnail": { + "Height": 125, + "Url": "http://www.example.com/image/481989943", + "Width": 100 + }, + "Title": "View from 15th Floor", + "Width": 800 + } +} + diff --git a/doc/examples/parse__contiguouscontainer__parser_callback_t.cpp b/doc/examples/parse__contiguouscontainer__parser_callback_t.cpp new file mode 100644 index 00000000..5a339079 --- /dev/null +++ b/doc/examples/parse__contiguouscontainer__parser_callback_t.cpp @@ -0,0 +1,13 @@ +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text given as std::vector + std::vector text = {'[', '1', ',', '2', ',', '3', ']', '\0'}; + + // parse and serialize JSON + json j_complete = json::parse(text); + std::cout << std::setw(4) << j_complete << "\n\n"; +} diff --git a/doc/examples/parse__contiguouscontainer__parser_callback_t.link b/doc/examples/parse__contiguouscontainer__parser_callback_t.link new file mode 100644 index 00000000..57d6dc3a --- /dev/null +++ b/doc/examples/parse__contiguouscontainer__parser_callback_t.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/parse__contiguouscontainer__parser_callback_t.output b/doc/examples/parse__contiguouscontainer__parser_callback_t.output new file mode 100644 index 00000000..74633e80 --- /dev/null +++ b/doc/examples/parse__contiguouscontainer__parser_callback_t.output @@ -0,0 +1,6 @@ +[ + 1, + 2, + 3 +] + diff --git a/doc/examples/parse__iteratortype__parser_callback_t.cpp b/doc/examples/parse__iteratortype__parser_callback_t.cpp new file mode 100644 index 00000000..3f723c5f --- /dev/null +++ b/doc/examples/parse__iteratortype__parser_callback_t.cpp @@ -0,0 +1,13 @@ +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text given as std::vector + std::vector text = {'[', '1', ',', '2', ',', '3', ']', '\0'}; + + // parse and serialize JSON + json j_complete = json::parse(text.begin(), text.end()); + std::cout << std::setw(4) << j_complete << "\n\n"; +} diff --git a/doc/examples/parse__iteratortype__parser_callback_t.link b/doc/examples/parse__iteratortype__parser_callback_t.link new file mode 100644 index 00000000..63f58fe6 --- /dev/null +++ b/doc/examples/parse__iteratortype__parser_callback_t.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/parse__iteratortype__parser_callback_t.output b/doc/examples/parse__iteratortype__parser_callback_t.output new file mode 100644 index 00000000..74633e80 --- /dev/null +++ b/doc/examples/parse__iteratortype__parser_callback_t.output @@ -0,0 +1,6 @@ +[ + 1, + 2, + 3 +] + diff --git a/doc/examples/parse__string__parser_callback_t.cpp b/doc/examples/parse__string__parser_callback_t.cpp index 62982ca6..0a4f3b53 100644 --- a/doc/examples/parse__string__parser_callback_t.cpp +++ b/doc/examples/parse__string__parser_callback_t.cpp @@ -5,7 +5,7 @@ using json = nlohmann::json; int main() { // a JSON text - std::string text = R"( + auto text = R"( { "Image": { "Width": 800, @@ -44,4 +44,4 @@ int main() // parse (with callback) and serialize JSON json j_filtered = json::parse(text, cb); std::cout << std::setw(4) << j_filtered << '\n'; -} \ No newline at end of file +} diff --git a/doc/examples/parse__string__parser_callback_t.link b/doc/examples/parse__string__parser_callback_t.link index 1ad3b719..292046b6 100644 --- a/doc/examples/parse__string__parser_callback_t.link +++ b/doc/examples/parse__string__parser_callback_t.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/src/json.hpp b/src/json.hpp index 8a1c9a77..0675a939 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -951,7 +951,7 @@ class basic_json With a parser callback function, the result of parsing a JSON text can be influenced. When passed to @ref parse(std::istream&, const - parser_callback_t) or @ref parse(const string_t&, const parser_callback_t), + parser_callback_t) or @ref parse(const char*, const parser_callback_t), it is called on certain events (passed as @ref parse_event_t via parameter @a event) with a set recursion depth @a depth and context JSON value @a parsed. The return value of the callback function is a boolean @@ -994,7 +994,7 @@ class basic_json skipped completely or replaced by an empty discarded object. @sa @ref parse(std::istream&, parser_callback_t) or - @ref parse(const string_t&, parser_callback_t) for examples + @ref parse(const char*, parser_callback_t) for examples @since version 1.0.0 */ @@ -5933,9 +5933,9 @@ class basic_json /// @{ /*! - @brief deserialize from string + @brief deserialize from string literal - @param[in] s string to read a serialized JSON value from + @param[in] s string literal to read a serialized JSON value from @param[in] cb a parser callback function of type @ref parser_callback_t which is used to control the deserialization by filtering unwanted values (optional) @@ -5947,6 +5947,8 @@ class basic_json @a cb has a super-linear complexity. @note A UTF-8 byte order mark is silently ignored. + @note String containers like `std::string` or @ref string_t can be parsed + with @ref parse(const ContiguousContainer&, const parser_callback_t) @liveexample{The example below demonstrates the `parse()` function with and without callback function.,parse__string__parser_callback_t} @@ -5954,24 +5956,47 @@ class basic_json @sa @ref parse(std::istream&, const parser_callback_t) for a version that reads from an input stream - @since version 1.0.0 + @since version 1.0.0 (originally for @ref string_t) */ - /* - static basic_json parse(const string_t& s, + static basic_json parse(const char* s, const parser_callback_t cb = nullptr) { return parser(s, cb).parse(); } - */ /*! - @brief deserialize from string literal - @copydoc parse(const string_t&, const parser_callback_t) + @brief deserialize from an array + + This function reads from an array of 1-byte values. + + @pre Each element of the container has a size of 1 byte. Violating this + precondition yields undefined behavior. **This precondition is enforced + with a static assertion.** + + @param[in] array array to read from + @param[in] cb a parser callback function of type @ref parser_callback_t + which is used to control the deserialization by filtering unwanted values + (optional) + + @return result of the deserialization + + @complexity Linear in the length of the input. The parser is a predictive + LL(1) parser. The complexity can be higher if the parser callback function + @a cb has a super-linear complexity. + + @note A UTF-8 byte order mark is silently ignored. + + @liveexample{The example below demonstrates the `parse()` function reading + from an array.,parse__array__parser_callback_t} + + @since version 2.0.3 */ - static basic_json parse(const typename string_t::value_type* s, + template + static basic_json parse(T (&array)[N], const parser_callback_t cb = nullptr) { - return parser(s, cb).parse(); + // delegate the call to the iterator-range parse overload + return parse(std::begin(array), std::end(array), cb); } /*! @@ -5993,7 +6018,7 @@ class basic_json @liveexample{The example below demonstrates the `parse()` function with and without callback function.,parse__istream__parser_callback_t} - @sa @ref parse(const string_t&, const parser_callback_t) for a version + @sa @ref parse(const char*, const parser_callback_t) for a version that reads from a string @since version 1.0.0 @@ -6014,7 +6039,7 @@ class basic_json } /*! - @brief deserialize from a iterator range with contiguous storage + @brief deserialize from an iterator range with contiguous storage This function reads from an iterator range of a container with contiguous storage of 1-byte values. Compatible container types include @@ -6029,13 +6054,14 @@ class basic_json precondition yields undefined behavior. **This precondition is enforced with a static assertion.** - @warning There is no way to enforce the preconditions at compile-time. If - the function is called with noncompliant iterators, the behavior - is undefined and will most liekely yield segmentation violation. + @warning There is no way to enforce all preconditions at compile-time. If + the function is called with noncompliant iterators and with + assertions switched off, the behavior is undefined and will most + likely yield segmentation violation. - @param[in] first begin of the range to parse (included) - @param[in] last end of the range to parse (excluded) - @param[in] cb a parser callback function of type @ref parser_callback_t + @param[in] first begin of the range to parse (included) + @param[in] last end of the range to parse (excluded) + @param[in] cb a parser callback function of type @ref parser_callback_t which is used to control the deserialization by filtering unwanted values (optional) @@ -6047,7 +6073,8 @@ class basic_json @note A UTF-8 byte order mark is silently ignored. - @todo Example and references. + @liveexample{The example below demonstrates the `parse()` function reading + from an iterator range.,parse__iteratortype__parser_callback_t} @since version 2.0.3 */ @@ -6084,6 +6111,45 @@ class basic_json return parser(first, last, cb).parse(); } + /*! + @brief deserialize from a container with contiguous storage + + This function reads from a container with contiguous storage of 1-byte + values. Compatible container types include `std::vector`, `std::string`, + `std::array`, and `std::initializer_list`. User-defined containers can be + used as long as they implement random-access iterators and a contiguous + storage. + + @pre The container storage is contiguous. Violating this precondition + yields undefined behavior. **This precondition is enforced with an + assertion.** + @pre Each element of the container has a size of 1 byte. Violating this + precondition yields undefined behavior. **This precondition is enforced + with a static assertion.** + + @warning There is no way to enforce all preconditions at compile-time. If + the function is called with a noncompliant container and with + assertions switched off, the behavior is undefined and will most + likely yield segmentation violation. + + @param[in] c container to read from + @param[in] cb a parser callback function of type @ref parser_callback_t + which is used to control the deserialization by filtering unwanted values + (optional) + + @return result of the deserialization + + @complexity Linear in the length of the input. The parser is a predictive + LL(1) parser. The complexity can be higher if the parser callback function + @a cb has a super-linear complexity. + + @note A UTF-8 byte order mark is silently ignored. + + @liveexample{The example below demonstrates the `parse()` function reading + from a contiguous container.,parse__contiguouscontainer__parser_callback_t} + + @since version 2.0.3 + */ template - static basic_json parse(T (&array)[N], - const parser_callback_t cb = nullptr) - { - // delegate the call to the iterator-range parse overload - return parse(std::begin(array), std::end(array), cb); - } - /*! @brief deserialize from stream @@ -6158,7 +6216,7 @@ class basic_json Returns the type name as string to be used in error messages - usually to indicate that a function was called on a wrong JSON type. - @return basically a string representation of a the @ref m_type member + @return basically a string representation of a the @a m_type member @complexity Constant. @@ -7626,7 +7684,7 @@ class basic_json fill_line_buffer(); } - // switch off unwanted functions + // switch off unwanted functions (due to pointer members) lexer() = delete; lexer(const lexer&) = delete; lexer operator=(const lexer&) = delete; @@ -8979,24 +9037,17 @@ basic_json_parser_63: { public: /// a parser reading from a string literal - parser(const typename string_t::value_type* buff, - const parser_callback_t cb = nullptr) + parser(const char* buff, const parser_callback_t cb = nullptr) : callback(cb), m_lexer(reinterpret_cast(buff), strlen(buff)) {} - /// a parser reading from a string container - parser(const string_t& s, const parser_callback_t cb = nullptr) - : callback(cb), - m_lexer(reinterpret_cast(s.c_str()), s.size()) - {} - /// a parser reading from an input stream parser(std::istream& is, const parser_callback_t cb = nullptr) : callback(cb), m_lexer(is) {} - /// a parser reading from a container with contiguous storage + /// a parser reading from an iterator range with contiguous storage template ::iterator_category, std::random_access_iterator_tag>::value @@ -10560,7 +10611,7 @@ if no parse error occurred. */ inline nlohmann::json operator "" _json(const char* s, std::size_t) { - return nlohmann::json::parse(reinterpret_cast(s)); + return nlohmann::json::parse(s); } /*! diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index cb51f557..f56c5d3f 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -951,7 +951,7 @@ class basic_json With a parser callback function, the result of parsing a JSON text can be influenced. When passed to @ref parse(std::istream&, const - parser_callback_t) or @ref parse(const string_t&, const parser_callback_t), + parser_callback_t) or @ref parse(const char*, const parser_callback_t), it is called on certain events (passed as @ref parse_event_t via parameter @a event) with a set recursion depth @a depth and context JSON value @a parsed. The return value of the callback function is a boolean @@ -994,7 +994,7 @@ class basic_json skipped completely or replaced by an empty discarded object. @sa @ref parse(std::istream&, parser_callback_t) or - @ref parse(const string_t&, parser_callback_t) for examples + @ref parse(const char*, parser_callback_t) for examples @since version 1.0.0 */ @@ -5933,9 +5933,9 @@ class basic_json /// @{ /*! - @brief deserialize from string + @brief deserialize from string literal - @param[in] s string to read a serialized JSON value from + @param[in] s string literal to read a serialized JSON value from @param[in] cb a parser callback function of type @ref parser_callback_t which is used to control the deserialization by filtering unwanted values (optional) @@ -5947,6 +5947,8 @@ class basic_json @a cb has a super-linear complexity. @note A UTF-8 byte order mark is silently ignored. + @note String containers like `std::string` or @ref string_t can be parsed + with @ref parse(const ContiguousContainer&, const parser_callback_t) @liveexample{The example below demonstrates the `parse()` function with and without callback function.,parse__string__parser_callback_t} @@ -5954,24 +5956,47 @@ class basic_json @sa @ref parse(std::istream&, const parser_callback_t) for a version that reads from an input stream - @since version 1.0.0 + @since version 1.0.0 (originally for @ref string_t) */ - /* - static basic_json parse(const string_t& s, + static basic_json parse(const char* s, const parser_callback_t cb = nullptr) { return parser(s, cb).parse(); } - */ /*! - @brief deserialize from string literal - @copydoc parse(const string_t&, const parser_callback_t) + @brief deserialize from an array + + This function reads from an array of 1-byte values. + + @pre Each element of the container has a size of 1 byte. Violating this + precondition yields undefined behavior. **This precondition is enforced + with a static assertion.** + + @param[in] array array to read from + @param[in] cb a parser callback function of type @ref parser_callback_t + which is used to control the deserialization by filtering unwanted values + (optional) + + @return result of the deserialization + + @complexity Linear in the length of the input. The parser is a predictive + LL(1) parser. The complexity can be higher if the parser callback function + @a cb has a super-linear complexity. + + @note A UTF-8 byte order mark is silently ignored. + + @liveexample{The example below demonstrates the `parse()` function reading + from an array.,parse__array__parser_callback_t} + + @since version 2.0.3 */ - static basic_json parse(const typename string_t::value_type* s, + template + static basic_json parse(T (&array)[N], const parser_callback_t cb = nullptr) { - return parser(s, cb).parse(); + // delegate the call to the iterator-range parse overload + return parse(std::begin(array), std::end(array), cb); } /*! @@ -5993,7 +6018,7 @@ class basic_json @liveexample{The example below demonstrates the `parse()` function with and without callback function.,parse__istream__parser_callback_t} - @sa @ref parse(const string_t&, const parser_callback_t) for a version + @sa @ref parse(const char*, const parser_callback_t) for a version that reads from a string @since version 1.0.0 @@ -6014,7 +6039,7 @@ class basic_json } /*! - @brief deserialize from a iterator range with contiguous storage + @brief deserialize from an iterator range with contiguous storage This function reads from an iterator range of a container with contiguous storage of 1-byte values. Compatible container types include @@ -6029,13 +6054,14 @@ class basic_json precondition yields undefined behavior. **This precondition is enforced with a static assertion.** - @warning There is no way to enforce the preconditions at compile-time. If - the function is called with noncompliant iterators, the behavior - is undefined and will most liekely yield segmentation violation. + @warning There is no way to enforce all preconditions at compile-time. If + the function is called with noncompliant iterators and with + assertions switched off, the behavior is undefined and will most + likely yield segmentation violation. - @param[in] first begin of the range to parse (included) - @param[in] last end of the range to parse (excluded) - @param[in] cb a parser callback function of type @ref parser_callback_t + @param[in] first begin of the range to parse (included) + @param[in] last end of the range to parse (excluded) + @param[in] cb a parser callback function of type @ref parser_callback_t which is used to control the deserialization by filtering unwanted values (optional) @@ -6047,7 +6073,8 @@ class basic_json @note A UTF-8 byte order mark is silently ignored. - @todo Example and references. + @liveexample{The example below demonstrates the `parse()` function reading + from an iterator range.,parse__iteratortype__parser_callback_t} @since version 2.0.3 */ @@ -6084,6 +6111,45 @@ class basic_json return parser(first, last, cb).parse(); } + /*! + @brief deserialize from a container with contiguous storage + + This function reads from a container with contiguous storage of 1-byte + values. Compatible container types include `std::vector`, `std::string`, + `std::array`, and `std::initializer_list`. User-defined containers can be + used as long as they implement random-access iterators and a contiguous + storage. + + @pre The container storage is contiguous. Violating this precondition + yields undefined behavior. **This precondition is enforced with an + assertion.** + @pre Each element of the container has a size of 1 byte. Violating this + precondition yields undefined behavior. **This precondition is enforced + with a static assertion.** + + @warning There is no way to enforce all preconditions at compile-time. If + the function is called with a noncompliant container and with + assertions switched off, the behavior is undefined and will most + likely yield segmentation violation. + + @param[in] c container to read from + @param[in] cb a parser callback function of type @ref parser_callback_t + which is used to control the deserialization by filtering unwanted values + (optional) + + @return result of the deserialization + + @complexity Linear in the length of the input. The parser is a predictive + LL(1) parser. The complexity can be higher if the parser callback function + @a cb has a super-linear complexity. + + @note A UTF-8 byte order mark is silently ignored. + + @liveexample{The example below demonstrates the `parse()` function reading + from a contiguous container.,parse__contiguouscontainer__parser_callback_t} + + @since version 2.0.3 + */ template - static basic_json parse(T (&array)[N], - const parser_callback_t cb = nullptr) - { - // delegate the call to the iterator-range parse overload - return parse(std::begin(array), std::end(array), cb); - } - /*! @brief deserialize from stream @@ -6158,7 +6216,7 @@ class basic_json Returns the type name as string to be used in error messages - usually to indicate that a function was called on a wrong JSON type. - @return basically a string representation of a the @ref m_type member + @return basically a string representation of a the @a m_type member @complexity Constant. @@ -7626,7 +7684,7 @@ class basic_json fill_line_buffer(); } - // switch off unwanted functions + // switch off unwanted functions (due to pointer members) lexer() = delete; lexer(const lexer&) = delete; lexer operator=(const lexer&) = delete; @@ -8276,24 +8334,17 @@ class basic_json { public: /// a parser reading from a string literal - parser(const typename string_t::value_type* buff, - const parser_callback_t cb = nullptr) + parser(const char* buff, const parser_callback_t cb = nullptr) : callback(cb), m_lexer(reinterpret_cast(buff), strlen(buff)) {} - /// a parser reading from a string container - parser(const string_t& s, const parser_callback_t cb = nullptr) - : callback(cb), - m_lexer(reinterpret_cast(s.c_str()), s.size()) - {} - /// a parser reading from an input stream parser(std::istream& is, const parser_callback_t cb = nullptr) : callback(cb), m_lexer(is) {} - /// a parser reading from a container with contiguous storage + /// a parser reading from an iterator range with contiguous storage template ::iterator_category, std::random_access_iterator_tag>::value @@ -9857,7 +9908,7 @@ if no parse error occurred. */ inline nlohmann::json operator "" _json(const char* s, std::size_t) { - return nlohmann::json::parse(reinterpret_cast(s)); + return nlohmann::json::parse(s); } /*! diff --git a/test/src/unit-class_parser.cpp b/test/src/unit-class_parser.cpp index 775952b9..5cae3071 100644 --- a/test/src/unit-class_parser.cpp +++ b/test/src/unit-class_parser.cpp @@ -477,7 +477,7 @@ TEST_CASE("parser class") case ('r'): case ('t'): { - CHECK_NOTHROW(json::parser(s).parse()); + CHECK_NOTHROW(json::parser(s.c_str()).parse()); break; } @@ -490,8 +490,8 @@ TEST_CASE("parser class") // any other combination of backslash and character is invalid default: { - CHECK_THROWS_AS(json::parser(s).parse(), std::invalid_argument); - CHECK_THROWS_WITH(json::parser(s).parse(), "parse error - unexpected '\"'"); + CHECK_THROWS_AS(json::parser(s.c_str()).parse(), std::invalid_argument); + CHECK_THROWS_WITH(json::parser(s.c_str()).parse(), "parse error - unexpected '\"'"); break; } } @@ -549,22 +549,22 @@ TEST_CASE("parser class") if (valid(c)) { - CHECK_NOTHROW(json::parser(s1).parse()); - CHECK_NOTHROW(json::parser(s2).parse()); - CHECK_NOTHROW(json::parser(s3).parse()); - CHECK_NOTHROW(json::parser(s4).parse()); + CHECK_NOTHROW(json::parser(s1.c_str()).parse()); + CHECK_NOTHROW(json::parser(s2.c_str()).parse()); + CHECK_NOTHROW(json::parser(s3.c_str()).parse()); + CHECK_NOTHROW(json::parser(s4.c_str()).parse()); } else { - CHECK_THROWS_AS(json::parser(s1).parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser(s2).parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser(s3).parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser(s4).parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser(s1.c_str()).parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser(s2.c_str()).parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser(s3.c_str()).parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser(s4.c_str()).parse(), std::invalid_argument); - CHECK_THROWS_WITH(json::parser(s1).parse(), "parse error - unexpected '\"'"); - CHECK_THROWS_WITH(json::parser(s2).parse(), "parse error - unexpected '\"'"); - CHECK_THROWS_WITH(json::parser(s3).parse(), "parse error - unexpected '\"'"); - CHECK_THROWS_WITH(json::parser(s4).parse(), "parse error - unexpected '\"'"); + CHECK_THROWS_WITH(json::parser(s1.c_str()).parse(), "parse error - unexpected '\"'"); + CHECK_THROWS_WITH(json::parser(s2.c_str()).parse(), "parse error - unexpected '\"'"); + CHECK_THROWS_WITH(json::parser(s3.c_str()).parse(), "parse error - unexpected '\"'"); + CHECK_THROWS_WITH(json::parser(s4.c_str()).parse(), "parse error - unexpected '\"'"); } } } diff --git a/test/src/unit-deserialization.cpp b/test/src/unit-deserialization.cpp index b681e3df..6e2c7813 100644 --- a/test/src/unit-deserialization.cpp +++ b/test/src/unit-deserialization.cpp @@ -113,6 +113,12 @@ TEST_CASE("deserialization") std::initializer_list v = {'t', 'r', 'u', 'e', '\0'}; CHECK(json::parse(v) == json(true)); } + + SECTION("empty container") + { + std::vector v; + CHECK_THROWS_AS(json::parse(v), std::invalid_argument); + } } SECTION("via iterator range")