Merge branch 'develop' into feature/iterator_range_parsing
This commit is contained in:
commit
ae7aaed4ac
13 changed files with 160 additions and 136 deletions
|
@ -1,12 +0,0 @@
|
||||||
#include <json.hpp>
|
|
||||||
|
|
||||||
using json = nlohmann::json;
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
// create a JSON value with default null value
|
|
||||||
json j;
|
|
||||||
|
|
||||||
// serialize the JSON null value
|
|
||||||
std::cout << j << '\n';
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
<a target="_blank" href="http://melpon.org/wandbox/permlink/dRptmFmhvpsYB49t"><b>online</b></a>
|
|
|
@ -1 +0,0 @@
|
||||||
null
|
|
|
@ -27,7 +27,8 @@ int main()
|
||||||
ss << text;
|
ss << text;
|
||||||
|
|
||||||
// create JSON from stream
|
// create JSON from stream
|
||||||
json j_complete(ss);
|
json j_complete(ss); // deprecated!
|
||||||
|
// shall be replaced by: json j_complete = json::parse(ss);
|
||||||
std::cout << std::setw(4) << j_complete << "\n\n";
|
std::cout << std::setw(4) << j_complete << "\n\n";
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,5 +52,6 @@ int main()
|
||||||
|
|
||||||
// create JSON from stream (with callback)
|
// create JSON from stream (with callback)
|
||||||
json j_filtered(ss, cb);
|
json j_filtered(ss, cb);
|
||||||
|
// shall be replaced by: json j_filtered = json::parse(ss, cb);
|
||||||
std::cout << std::setw(4) << j_filtered << '\n';
|
std::cout << std::setw(4) << j_filtered << '\n';
|
||||||
}
|
}
|
|
@ -1 +1 @@
|
||||||
<a target="_blank" href="http://melpon.org/wandbox/permlink/VzSqLszbnoWE92dD"><b>online</b></a>
|
<a target="_blank" href="http://melpon.org/wandbox/permlink/R6dzpKXlxrttShf7"><b>online</b></a>
|
|
@ -4,9 +4,12 @@ using json = nlohmann::json;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// create a JSON null value
|
// implicitly create a JSON null value
|
||||||
json j(nullptr);
|
json j1;
|
||||||
|
|
||||||
|
// explicitly create a JSON null value
|
||||||
|
json j2(nullptr);
|
||||||
|
|
||||||
// serialize the JSON null value
|
// serialize the JSON null value
|
||||||
std::cout << j << '\n';
|
std::cout << j1 << '\n' << j2 << '\n';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<a target="_blank" href="http://melpon.org/wandbox/permlink/PMMpoM0ujdJDsuta"><b>online</b></a>
|
<a target="_blank" href="http://melpon.org/wandbox/permlink/9Tvfs2dJBW8m8ihA"><b>online</b></a>
|
|
@ -1 +1,2 @@
|
||||||
null
|
null
|
||||||
|
null
|
||||||
|
|
65
src/json.hpp
65
src/json.hpp
|
@ -74,6 +74,15 @@ SOFTWARE.
|
||||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// allow for portable deprecation warnings
|
||||||
|
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
|
||||||
|
#define JSON_DEPRECATED __attribute__((deprecated))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define JSON_DEPRECATED __declspec(deprecated)
|
||||||
|
#else
|
||||||
|
#define JSON_DEPRECATED
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief namespace for Niels Lohmann
|
@brief namespace for Niels Lohmann
|
||||||
@see https://github.com/nlohmann
|
@see https://github.com/nlohmann
|
||||||
|
@ -1058,40 +1067,10 @@ class basic_json
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief create a null object (implicitly)
|
@brief create a null object
|
||||||
|
|
||||||
Create a `null` JSON value. This is the implicit version of the `null`
|
Create a `null` JSON value. It either takes a null pointer as parameter
|
||||||
value constructor as it takes no parameters.
|
(explicitly creating `null`) or no parameter (implicitly creating `null`).
|
||||||
|
|
||||||
@note The class invariant is satisfied, because it poses no requirements
|
|
||||||
for null values.
|
|
||||||
|
|
||||||
@complexity Constant.
|
|
||||||
|
|
||||||
@exceptionsafety No-throw guarantee: this constructor never throws
|
|
||||||
exceptions.
|
|
||||||
|
|
||||||
@requirement This function helps `basic_json` satisfying the
|
|
||||||
[Container](http://en.cppreference.com/w/cpp/concept/Container)
|
|
||||||
requirements:
|
|
||||||
- The complexity is constant.
|
|
||||||
- As postcondition, it holds: `basic_json().empty() == true`.
|
|
||||||
|
|
||||||
@liveexample{The following code shows the constructor for a `null` JSON
|
|
||||||
value.,basic_json}
|
|
||||||
|
|
||||||
@sa @ref basic_json(std::nullptr_t) -- create a `null` value
|
|
||||||
|
|
||||||
@since version 1.0.0
|
|
||||||
*/
|
|
||||||
basic_json() = default;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief create a null object (explicitly)
|
|
||||||
|
|
||||||
Create a `null` JSON value. This is the explicitly version of the `null`
|
|
||||||
value constructor as it takes a null pointer as parameter. It allows to
|
|
||||||
create `null` values by explicitly assigning a `nullptr` to a JSON value.
|
|
||||||
The passed null pointer itself is not read -- it is only used to choose
|
The passed null pointer itself is not read -- it is only used to choose
|
||||||
the right constructor.
|
the right constructor.
|
||||||
|
|
||||||
|
@ -1100,15 +1079,12 @@ class basic_json
|
||||||
@exceptionsafety No-throw guarantee: this constructor never throws
|
@exceptionsafety No-throw guarantee: this constructor never throws
|
||||||
exceptions.
|
exceptions.
|
||||||
|
|
||||||
@liveexample{The following code shows the constructor with null pointer
|
@liveexample{The following code shows the constructor with and without a
|
||||||
parameter.,basic_json__nullptr_t}
|
null pointer parameter.,basic_json__nullptr_t}
|
||||||
|
|
||||||
@sa @ref basic_json() -- default constructor (implicitly creating a `null`
|
|
||||||
value)
|
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
*/
|
*/
|
||||||
basic_json(std::nullptr_t) noexcept
|
basic_json(std::nullptr_t = nullptr) noexcept
|
||||||
: basic_json(value_t::null)
|
: basic_json(value_t::null)
|
||||||
{
|
{
|
||||||
assert_invariant();
|
assert_invariant();
|
||||||
|
@ -1951,12 +1927,21 @@ class basic_json
|
||||||
|
|
||||||
@note A UTF-8 byte order mark is silently ignored.
|
@note A UTF-8 byte order mark is silently ignored.
|
||||||
|
|
||||||
|
@deprecated This constructor is deprecated and will be removed in version
|
||||||
|
3.0.0 to unify the interface of the library. Deserialization will be
|
||||||
|
done by stream operators or by calling one of the `parse` functions,
|
||||||
|
e.g. @ref parse(std::istream&, const parser_callback_t). That is, calls
|
||||||
|
like `json j(i);` for an input stream @a i need to be replaced by
|
||||||
|
`json j = json::parse(i);`. See the example below.
|
||||||
|
|
||||||
@liveexample{The example below demonstrates constructing a JSON value from
|
@liveexample{The example below demonstrates constructing a JSON value from
|
||||||
a `std::stringstream` with and without callback
|
a `std::stringstream` with and without callback
|
||||||
function.,basic_json__istream}
|
function.,basic_json__istream}
|
||||||
|
|
||||||
@since version 2.0.0
|
@since version 2.0.0, deprecated in version 2.0.3, to be removed in
|
||||||
|
version 3.0.0
|
||||||
*/
|
*/
|
||||||
|
JSON_DEPRECATED
|
||||||
explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)
|
explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)
|
||||||
{
|
{
|
||||||
*this = parser(i, cb).parse();
|
*this = parser(i, cb).parse();
|
||||||
|
|
|
@ -74,6 +74,15 @@ SOFTWARE.
|
||||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// allow for portable deprecation warnings
|
||||||
|
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
|
||||||
|
#define JSON_DEPRECATED __attribute__((deprecated))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define JSON_DEPRECATED __declspec(deprecated)
|
||||||
|
#else
|
||||||
|
#define JSON_DEPRECATED
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief namespace for Niels Lohmann
|
@brief namespace for Niels Lohmann
|
||||||
@see https://github.com/nlohmann
|
@see https://github.com/nlohmann
|
||||||
|
@ -1058,40 +1067,10 @@ class basic_json
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief create a null object (implicitly)
|
@brief create a null object
|
||||||
|
|
||||||
Create a `null` JSON value. This is the implicit version of the `null`
|
Create a `null` JSON value. It either takes a null pointer as parameter
|
||||||
value constructor as it takes no parameters.
|
(explicitly creating `null`) or no parameter (implicitly creating `null`).
|
||||||
|
|
||||||
@note The class invariant is satisfied, because it poses no requirements
|
|
||||||
for null values.
|
|
||||||
|
|
||||||
@complexity Constant.
|
|
||||||
|
|
||||||
@exceptionsafety No-throw guarantee: this constructor never throws
|
|
||||||
exceptions.
|
|
||||||
|
|
||||||
@requirement This function helps `basic_json` satisfying the
|
|
||||||
[Container](http://en.cppreference.com/w/cpp/concept/Container)
|
|
||||||
requirements:
|
|
||||||
- The complexity is constant.
|
|
||||||
- As postcondition, it holds: `basic_json().empty() == true`.
|
|
||||||
|
|
||||||
@liveexample{The following code shows the constructor for a `null` JSON
|
|
||||||
value.,basic_json}
|
|
||||||
|
|
||||||
@sa @ref basic_json(std::nullptr_t) -- create a `null` value
|
|
||||||
|
|
||||||
@since version 1.0.0
|
|
||||||
*/
|
|
||||||
basic_json() = default;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief create a null object (explicitly)
|
|
||||||
|
|
||||||
Create a `null` JSON value. This is the explicitly version of the `null`
|
|
||||||
value constructor as it takes a null pointer as parameter. It allows to
|
|
||||||
create `null` values by explicitly assigning a `nullptr` to a JSON value.
|
|
||||||
The passed null pointer itself is not read -- it is only used to choose
|
The passed null pointer itself is not read -- it is only used to choose
|
||||||
the right constructor.
|
the right constructor.
|
||||||
|
|
||||||
|
@ -1100,15 +1079,12 @@ class basic_json
|
||||||
@exceptionsafety No-throw guarantee: this constructor never throws
|
@exceptionsafety No-throw guarantee: this constructor never throws
|
||||||
exceptions.
|
exceptions.
|
||||||
|
|
||||||
@liveexample{The following code shows the constructor with null pointer
|
@liveexample{The following code shows the constructor with and without a
|
||||||
parameter.,basic_json__nullptr_t}
|
null pointer parameter.,basic_json__nullptr_t}
|
||||||
|
|
||||||
@sa @ref basic_json() -- default constructor (implicitly creating a `null`
|
|
||||||
value)
|
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
*/
|
*/
|
||||||
basic_json(std::nullptr_t) noexcept
|
basic_json(std::nullptr_t = nullptr) noexcept
|
||||||
: basic_json(value_t::null)
|
: basic_json(value_t::null)
|
||||||
{
|
{
|
||||||
assert_invariant();
|
assert_invariant();
|
||||||
|
@ -1951,12 +1927,21 @@ class basic_json
|
||||||
|
|
||||||
@note A UTF-8 byte order mark is silently ignored.
|
@note A UTF-8 byte order mark is silently ignored.
|
||||||
|
|
||||||
|
@deprecated This constructor is deprecated and will be removed in version
|
||||||
|
3.0.0 to unify the interface of the library. Deserialization will be
|
||||||
|
done by stream operators or by calling one of the `parse` functions,
|
||||||
|
e.g. @ref parse(std::istream&, const parser_callback_t). That is, calls
|
||||||
|
like `json j(i);` for an input stream @a i need to be replaced by
|
||||||
|
`json j = json::parse(i);`. See the example below.
|
||||||
|
|
||||||
@liveexample{The example below demonstrates constructing a JSON value from
|
@liveexample{The example below demonstrates constructing a JSON value from
|
||||||
a `std::stringstream` with and without callback
|
a `std::stringstream` with and without callback
|
||||||
function.,basic_json__istream}
|
function.,basic_json__istream}
|
||||||
|
|
||||||
@since version 2.0.0
|
@since version 2.0.0, deprecated in version 2.0.3, to be removed in
|
||||||
|
version 3.0.0
|
||||||
*/
|
*/
|
||||||
|
JSON_DEPRECATED
|
||||||
explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)
|
explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)
|
||||||
{
|
{
|
||||||
*this = parser(i, cb).parse();
|
*this = parser(i, cb).parse();
|
||||||
|
|
|
@ -64,6 +64,22 @@ TEST_CASE("const_iterator class")
|
||||||
json::const_iterator it2(&j);
|
json::const_iterator it2(&j);
|
||||||
it2 = it;
|
it2 = it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("copy constructor from non-const iterator")
|
||||||
|
{
|
||||||
|
SECTION("create from uninitialized iterator")
|
||||||
|
{
|
||||||
|
const json::iterator it {};
|
||||||
|
json::const_iterator cit(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("create from initialized iterator")
|
||||||
|
{
|
||||||
|
json j;
|
||||||
|
const json::iterator it = j.begin();
|
||||||
|
json::const_iterator cit(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("initialization")
|
SECTION("initialization")
|
||||||
|
|
|
@ -709,7 +709,7 @@ TEST_CASE("constructors")
|
||||||
|
|
||||||
SECTION("float")
|
SECTION("float")
|
||||||
{
|
{
|
||||||
float n = 42.23;
|
float n = 42.23f;
|
||||||
json j(n);
|
json j(n);
|
||||||
CHECK(j.type() == json::value_t::number_float);
|
CHECK(j.type() == json::value_t::number_float);
|
||||||
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
|
CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float));
|
||||||
|
|
|
@ -35,49 +35,95 @@ using nlohmann::json;
|
||||||
|
|
||||||
TEST_CASE("deserialization")
|
TEST_CASE("deserialization")
|
||||||
{
|
{
|
||||||
SECTION("stream")
|
SECTION("successful deserialization")
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
SECTION("stream")
|
||||||
ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
|
{
|
||||||
json j = json::parse(ss);
|
std::stringstream ss;
|
||||||
CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
|
||||||
|
json j = json::parse(ss);
|
||||||
|
CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("string literal")
|
||||||
|
{
|
||||||
|
auto s = "[\"foo\",1,2,3,false,{\"one\":1}]";
|
||||||
|
json j = json::parse(s);
|
||||||
|
CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("string_t")
|
||||||
|
{
|
||||||
|
json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}]";
|
||||||
|
json j = json::parse(s);
|
||||||
|
CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("operator<<")
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
|
||||||
|
json j;
|
||||||
|
j << ss;
|
||||||
|
CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("operator>>")
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
|
||||||
|
json j;
|
||||||
|
ss >> j;
|
||||||
|
CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("user-defined string literal")
|
||||||
|
{
|
||||||
|
CHECK("[\"foo\",1,2,3,false,{\"one\":1}]"_json == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("string literal")
|
SECTION("unsuccessful deserialization")
|
||||||
{
|
{
|
||||||
auto s = "[\"foo\",1,2,3,false,{\"one\":1}]";
|
SECTION("stream")
|
||||||
json j = json::parse(s);
|
{
|
||||||
CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
std::stringstream ss;
|
||||||
}
|
ss << "[\"foo\",1,2,3,false,{\"one\":1}";
|
||||||
|
CHECK_THROWS_AS(json::parse(ss), std::invalid_argument);
|
||||||
|
CHECK_THROWS_WITH(json::parse(ss), "parse error - unexpected end of input");
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("string_t")
|
SECTION("string")
|
||||||
{
|
{
|
||||||
json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}]";
|
json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}";
|
||||||
json j = json::parse(s);
|
CHECK_THROWS_AS(json::parse(s), std::invalid_argument);
|
||||||
CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
CHECK_THROWS_WITH(json::parse(s), "parse error - unexpected end of input; expected ']'");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("operator<<")
|
SECTION("operator<<")
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
|
ss << "[\"foo\",1,2,3,false,{\"one\":1}";
|
||||||
json j;
|
json j;
|
||||||
j << ss;
|
CHECK_THROWS_AS(j << ss, std::invalid_argument);
|
||||||
CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("operator>>")
|
SECTION("operator>>")
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "[\"foo\",1,2,3,false,{\"one\":1}]";
|
ss << "[\"foo\",1,2,3,false,{\"one\":1}";
|
||||||
json j;
|
json j;
|
||||||
ss >> j;
|
CHECK_THROWS_AS(ss >> j, std::invalid_argument);
|
||||||
CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
CHECK_THROWS_WITH(ss >> j, "parse error - unexpected end of input");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("user-defined string literal")
|
SECTION("user-defined string literal")
|
||||||
{
|
{
|
||||||
CHECK("[\"foo\",1,2,3,false,{\"one\":1}]"_json == json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
CHECK_THROWS_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, std::invalid_argument);
|
||||||
|
CHECK_THROWS_WITH("[\"foo\",1,2,3,false,{\"one\":1}"_json,
|
||||||
|
"parse error - unexpected end of input; expected ']'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("contiguous containers")
|
SECTION("contiguous containers")
|
||||||
|
|
Loading…
Reference in a new issue