From e0ff1a837c889e73eada0105758fd903d06c3cf7 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Thu, 25 Aug 2016 00:24:33 +0200 Subject: [PATCH 1/5] unit-constructor1.cpp: Fix floating point truncation warning --- test/src/unit-constructor1.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/unit-constructor1.cpp b/test/src/unit-constructor1.cpp index 87728648..8a26738b 100644 --- a/test/src/unit-constructor1.cpp +++ b/test/src/unit-constructor1.cpp @@ -709,7 +709,7 @@ TEST_CASE("constructors") SECTION("float") { - float n = 42.23; + float n = 42.23f; json j(n); CHECK(j.type() == json::value_t::number_float); CHECK(j.m_value.number_float == Approx(j_reference.m_value.number_float)); From a485aa8d272f3656c1fb5840ce100f3288f7e2da Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 30 Aug 2016 23:44:15 +0200 Subject: [PATCH 2/5] cleanup and improvement of branch coverage --- src/json.hpp | 218 ++++++++++--------------- src/json.hpp.re2c | 218 ++++++++++--------------- test/src/unit-class_const_iterator.cpp | 16 ++ test/src/unit-deserialization.cpp | 104 ++++++++---- 4 files changed, 265 insertions(+), 291 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index d6f8925f..2f0f02d5 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -1164,11 +1164,10 @@ class basic_json @since version 1.0.0 */ - template ::value and - std::is_constructible::value, int>::type - = 0> + template::value and + std::is_constructible::value, int>::type + = 0> basic_json(const CompatibleObjectType& val) : m_type(value_t::object) { @@ -1229,16 +1228,15 @@ class basic_json @since version 1.0.0 */ - template ::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - std::is_constructible::value, int>::type - = 0> + template::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + std::is_constructible::value, int>::type + = 0> basic_json(const CompatibleArrayType& val) : m_type(value_t::array) { @@ -1324,10 +1322,9 @@ class basic_json @since version 1.0.0 */ - template ::value, int>::type - = 0> + template::value, int>::type + = 0> basic_json(const CompatibleStringType& val) : basic_json(string_t(val)) { @@ -1377,8 +1374,7 @@ class basic_json @since version 1.0.0 */ - template::value) and std::is_same::value , int>::type @@ -1477,8 +1473,7 @@ class basic_json @since version 2.0.0 */ - template::value) and std::is_same::value , int>::type @@ -1509,13 +1504,11 @@ class basic_json @since version 2.0.0 */ - template ::value and - std::numeric_limits::is_integer and - not std::numeric_limits::is_signed, - CompatibleNumberUnsignedType>::type - = 0> + template::value and + std::numeric_limits::is_integer and + not std::numeric_limits::is_signed, CompatibleNumberUnsignedType>::type + = 0> basic_json(const CompatibleNumberUnsignedType val) noexcept : m_type(value_t::number_unsigned), m_value(static_cast(val)) @@ -1591,11 +1584,9 @@ class basic_json @since version 1.0.0 */ - template::value and - std::is_floating_point::value>::type - > + std::is_floating_point::value>::type> basic_json(const CompatibleNumberFloatType val) noexcept : basic_json(number_float_t(val)) { @@ -1672,8 +1663,8 @@ class basic_json @since version 1.0.0 */ basic_json(std::initializer_list init, - bool type_deduction = true, - value_t manual_type = value_t::array) + const bool type_deduction = true, + const value_t manual_type = value_t::array) { // check if each element is an array with two elements whose first // element is a string @@ -1862,12 +1853,9 @@ class basic_json @since version 1.0.0 */ - template ::value or - std::is_same::value - , int>::type - = 0> + template::value or + std::is_same::value>::type> basic_json(InputIT first, InputIT last) { assert(first.m_object != nullptr); @@ -2616,11 +2604,10 @@ class basic_json ////////////////// /// get an object (explicit) - template ::value and - std::is_convertible::value - , int>::type = 0> + template::value and + std::is_convertible::value + , int>::type = 0> T get_impl(T*) const { if (is_object()) @@ -2647,14 +2634,13 @@ class basic_json } /// get an array (explicit) - template ::value and - not std::is_same::value and - not std::is_arithmetic::value and - not std::is_convertible::value and - not has_mapped_type::value - , int>::type = 0> + template::value and + not std::is_same::value and + not std::is_arithmetic::value and + not std::is_convertible::value and + not has_mapped_type::value + , int>::type = 0> T get_impl(T*) const { if (is_array()) @@ -2674,11 +2660,10 @@ class basic_json } /// get an array (explicit) - template ::value and - not std::is_same::value - , int>::type = 0> + template::value and + not std::is_same::value + , int>::type = 0> std::vector get_impl(std::vector*) const { if (is_array()) @@ -2699,11 +2684,10 @@ class basic_json } /// get an array (explicit) - template ::value and - not has_mapped_type::value - , int>::type = 0> + template::value and + not has_mapped_type::value + , int>::type = 0> T get_impl(T*) const { if (is_array()) @@ -2730,10 +2714,9 @@ class basic_json } /// get a string (explicit) - template ::value - , int>::type = 0> + template::value + , int>::type = 0> T get_impl(T*) const { if (is_string()) @@ -2747,10 +2730,8 @@ class basic_json } /// get a number (explicit) - template::value - , int>::type = 0> + template::value, int>::type = 0> T get_impl(T*) const { switch (m_type) @@ -2939,10 +2920,8 @@ class basic_json @since version 1.0.0 */ - template::value - , int>::type = 0> + template::value>::type> ValueType get() const { return get_impl(static_cast(nullptr)); @@ -2975,10 +2954,8 @@ class basic_json @since version 1.0.0 */ - template::value - , int>::type = 0> + template::value>::type> PointerType get() noexcept { // delegate the call to get_ptr @@ -2989,10 +2966,8 @@ class basic_json @brief get a pointer value (explicit) @copydoc get() */ - template::value - , int>::type = 0> + template::value>::type> constexpr const PointerType get() const noexcept { // delegate the call to get_ptr @@ -3025,10 +3000,8 @@ class basic_json @since version 1.0.0 */ - template::value - , int>::type = 0> + template::value>::type> PointerType get_ptr() noexcept { // get the type of the PointerType (remove pointer and const) @@ -3054,11 +3027,9 @@ class basic_json @brief get a pointer value (implicit) @copydoc get_ptr() */ - template::value - and std::is_const::type>::value - , int>::type = 0> + and std::is_const::type>::value>::type> constexpr const PointerType get_ptr() const noexcept { // get the type of the PointerType (remove pointer and const) @@ -3106,10 +3077,8 @@ class basic_json @since version 1.1.0 */ - template::value - , int>::type = 0> + template::value>::type> ReferenceType get_ref() { // delegate call to get_ref_impl @@ -3120,11 +3089,9 @@ class basic_json @brief get a reference value (implicit) @copydoc get_ref() */ - template::value - and std::is_const::type>::value - , int>::type = 0> + and std::is_const::type>::value>::type> ReferenceType get_ref() const { // delegate call to get_ref_impl @@ -3159,14 +3126,13 @@ class basic_json @since version 1.0.0 */ - template < typename ValueType, typename - std::enable_if < + template < typename ValueType, typename = typename std::enable_if < not std::is_pointer::value and not std::is_same::value #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 and not std::is_same>::value #endif - , int >::type = 0 > + >::type > operator ValueType() const { // delegate the call to get<>() const @@ -3752,10 +3718,8 @@ class basic_json @since version 1.0.0 */ - template ::value - , int>::type = 0> + template::value>::type> ValueType value(const typename object_t::key_type& key, ValueType default_value) const { // at only works for objects @@ -3828,10 +3792,8 @@ class basic_json @since version 2.0.2 */ - template ::value - , int>::type = 0> + template::value>::type> ValueType value(const json_pointer& ptr, ValueType default_value) const { // at only works for objects @@ -3992,12 +3954,9 @@ class basic_json @since version 1.0.0 */ - template ::value or - std::is_same::value - , int>::type - = 0> + template::value or + std::is_same::value>::type> InteratorType erase(InteratorType pos) { // make sure iterator fits the current value @@ -4101,12 +4060,9 @@ class basic_json @since version 1.0.0 */ - template ::value or - std::is_same::value - , int>::type - = 0> + template::value or + std::is_same::value>::type> InteratorType erase(InteratorType first, InteratorType last) { // make sure iterator fits the current value @@ -6267,7 +6223,7 @@ class basic_json const unsigned int current_indent = 0) const { // variable to hold indentation for recursive calls - unsigned int new_indent = current_indent; + auto new_indent = current_indent; switch (m_type) { @@ -7561,7 +7517,7 @@ class basic_json const std::size_t codepoint2 = 0) { // calculate the code point from the given code points - std::size_t codepoint = codepoint1; + auto codepoint = codepoint1; // check if codepoint1 is a high surrogate if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF) @@ -9524,7 +9480,7 @@ basic_json_parser_63: auto reference_token = reference_string.substr(start, slash - start); // check reference tokens are properly escaped - for (size_t pos = reference_token.find_first_of("~"); + for (auto pos = reference_token.find_first_of("~"); pos != std::string::npos; pos = reference_token.find_first_of("~", pos + 1)) { @@ -9569,7 +9525,7 @@ basic_json_parser_63: assert(not f.empty()); for ( - size_t pos = s.find(f); // find first occurrence of f + auto pos = s.find(f); // find first occurrence of f pos != std::string::npos; // make sure f was found s.replace(pos, f.size(), t), // replace with t pos = s.find(f, pos + t.size()) // find next occurrence of f @@ -9969,7 +9925,7 @@ basic_json_parser_63: else { // make sure the top element of the pointer exists - json_pointer top_pointer = ptr.top(); + auto top_pointer = ptr.top(); if (top_pointer != ptr) { basic_json& x = result.at(top_pointer); @@ -10377,7 +10333,7 @@ namespace std @since version 1.0.0 */ -template <> +template<> inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( is_nothrow_move_constructible::value and @@ -10388,7 +10344,7 @@ inline void swap(nlohmann::json& j1, } /// hash value for JSON objects -template <> +template<> struct hash { /*! diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 75fc27e5..28532a8d 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -1164,11 +1164,10 @@ class basic_json @since version 1.0.0 */ - template ::value and - std::is_constructible::value, int>::type - = 0> + template::value and + std::is_constructible::value, int>::type + = 0> basic_json(const CompatibleObjectType& val) : m_type(value_t::object) { @@ -1229,16 +1228,15 @@ class basic_json @since version 1.0.0 */ - template ::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - std::is_constructible::value, int>::type - = 0> + template::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + std::is_constructible::value, int>::type + = 0> basic_json(const CompatibleArrayType& val) : m_type(value_t::array) { @@ -1324,10 +1322,9 @@ class basic_json @since version 1.0.0 */ - template ::value, int>::type - = 0> + template::value, int>::type + = 0> basic_json(const CompatibleStringType& val) : basic_json(string_t(val)) { @@ -1377,8 +1374,7 @@ class basic_json @since version 1.0.0 */ - template::value) and std::is_same::value , int>::type @@ -1477,8 +1473,7 @@ class basic_json @since version 2.0.0 */ - template::value) and std::is_same::value , int>::type @@ -1509,13 +1504,11 @@ class basic_json @since version 2.0.0 */ - template ::value and - std::numeric_limits::is_integer and - not std::numeric_limits::is_signed, - CompatibleNumberUnsignedType>::type - = 0> + template::value and + std::numeric_limits::is_integer and + not std::numeric_limits::is_signed, CompatibleNumberUnsignedType>::type + = 0> basic_json(const CompatibleNumberUnsignedType val) noexcept : m_type(value_t::number_unsigned), m_value(static_cast(val)) @@ -1591,11 +1584,9 @@ class basic_json @since version 1.0.0 */ - template::value and - std::is_floating_point::value>::type - > + std::is_floating_point::value>::type> basic_json(const CompatibleNumberFloatType val) noexcept : basic_json(number_float_t(val)) { @@ -1672,8 +1663,8 @@ class basic_json @since version 1.0.0 */ basic_json(std::initializer_list init, - bool type_deduction = true, - value_t manual_type = value_t::array) + const bool type_deduction = true, + const value_t manual_type = value_t::array) { // check if each element is an array with two elements whose first // element is a string @@ -1862,12 +1853,9 @@ class basic_json @since version 1.0.0 */ - template ::value or - std::is_same::value - , int>::type - = 0> + template::value or + std::is_same::value>::type> basic_json(InputIT first, InputIT last) { assert(first.m_object != nullptr); @@ -2616,11 +2604,10 @@ class basic_json ////////////////// /// get an object (explicit) - template ::value and - std::is_convertible::value - , int>::type = 0> + template::value and + std::is_convertible::value + , int>::type = 0> T get_impl(T*) const { if (is_object()) @@ -2647,14 +2634,13 @@ class basic_json } /// get an array (explicit) - template ::value and - not std::is_same::value and - not std::is_arithmetic::value and - not std::is_convertible::value and - not has_mapped_type::value - , int>::type = 0> + template::value and + not std::is_same::value and + not std::is_arithmetic::value and + not std::is_convertible::value and + not has_mapped_type::value + , int>::type = 0> T get_impl(T*) const { if (is_array()) @@ -2674,11 +2660,10 @@ class basic_json } /// get an array (explicit) - template ::value and - not std::is_same::value - , int>::type = 0> + template::value and + not std::is_same::value + , int>::type = 0> std::vector get_impl(std::vector*) const { if (is_array()) @@ -2699,11 +2684,10 @@ class basic_json } /// get an array (explicit) - template ::value and - not has_mapped_type::value - , int>::type = 0> + template::value and + not has_mapped_type::value + , int>::type = 0> T get_impl(T*) const { if (is_array()) @@ -2730,10 +2714,9 @@ class basic_json } /// get a string (explicit) - template ::value - , int>::type = 0> + template::value + , int>::type = 0> T get_impl(T*) const { if (is_string()) @@ -2747,10 +2730,8 @@ class basic_json } /// get a number (explicit) - template::value - , int>::type = 0> + template::value, int>::type = 0> T get_impl(T*) const { switch (m_type) @@ -2939,10 +2920,8 @@ class basic_json @since version 1.0.0 */ - template::value - , int>::type = 0> + template::value>::type> ValueType get() const { return get_impl(static_cast(nullptr)); @@ -2975,10 +2954,8 @@ class basic_json @since version 1.0.0 */ - template::value - , int>::type = 0> + template::value>::type> PointerType get() noexcept { // delegate the call to get_ptr @@ -2989,10 +2966,8 @@ class basic_json @brief get a pointer value (explicit) @copydoc get() */ - template::value - , int>::type = 0> + template::value>::type> constexpr const PointerType get() const noexcept { // delegate the call to get_ptr @@ -3025,10 +3000,8 @@ class basic_json @since version 1.0.0 */ - template::value - , int>::type = 0> + template::value>::type> PointerType get_ptr() noexcept { // get the type of the PointerType (remove pointer and const) @@ -3054,11 +3027,9 @@ class basic_json @brief get a pointer value (implicit) @copydoc get_ptr() */ - template::value - and std::is_const::type>::value - , int>::type = 0> + and std::is_const::type>::value>::type> constexpr const PointerType get_ptr() const noexcept { // get the type of the PointerType (remove pointer and const) @@ -3106,10 +3077,8 @@ class basic_json @since version 1.1.0 */ - template::value - , int>::type = 0> + template::value>::type> ReferenceType get_ref() { // delegate call to get_ref_impl @@ -3120,11 +3089,9 @@ class basic_json @brief get a reference value (implicit) @copydoc get_ref() */ - template::value - and std::is_const::type>::value - , int>::type = 0> + and std::is_const::type>::value>::type> ReferenceType get_ref() const { // delegate call to get_ref_impl @@ -3159,14 +3126,13 @@ class basic_json @since version 1.0.0 */ - template < typename ValueType, typename - std::enable_if < + template < typename ValueType, typename = typename std::enable_if < not std::is_pointer::value and not std::is_same::value #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 and not std::is_same>::value #endif - , int >::type = 0 > + >::type > operator ValueType() const { // delegate the call to get<>() const @@ -3752,10 +3718,8 @@ class basic_json @since version 1.0.0 */ - template ::value - , int>::type = 0> + template::value>::type> ValueType value(const typename object_t::key_type& key, ValueType default_value) const { // at only works for objects @@ -3828,10 +3792,8 @@ class basic_json @since version 2.0.2 */ - template ::value - , int>::type = 0> + template::value>::type> ValueType value(const json_pointer& ptr, ValueType default_value) const { // at only works for objects @@ -3992,12 +3954,9 @@ class basic_json @since version 1.0.0 */ - template ::value or - std::is_same::value - , int>::type - = 0> + template::value or + std::is_same::value>::type> InteratorType erase(InteratorType pos) { // make sure iterator fits the current value @@ -4101,12 +4060,9 @@ class basic_json @since version 1.0.0 */ - template ::value or - std::is_same::value - , int>::type - = 0> + template::value or + std::is_same::value>::type> InteratorType erase(InteratorType first, InteratorType last) { // make sure iterator fits the current value @@ -6267,7 +6223,7 @@ class basic_json const unsigned int current_indent = 0) const { // variable to hold indentation for recursive calls - unsigned int new_indent = current_indent; + auto new_indent = current_indent; switch (m_type) { @@ -7561,7 +7517,7 @@ class basic_json const std::size_t codepoint2 = 0) { // calculate the code point from the given code points - std::size_t codepoint = codepoint1; + auto codepoint = codepoint1; // check if codepoint1 is a high surrogate if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF) @@ -8821,7 +8777,7 @@ class basic_json auto reference_token = reference_string.substr(start, slash - start); // check reference tokens are properly escaped - for (size_t pos = reference_token.find_first_of("~"); + for (auto pos = reference_token.find_first_of("~"); pos != std::string::npos; pos = reference_token.find_first_of("~", pos + 1)) { @@ -8866,7 +8822,7 @@ class basic_json assert(not f.empty()); for ( - size_t pos = s.find(f); // find first occurrence of f + auto pos = s.find(f); // find first occurrence of f pos != std::string::npos; // make sure f was found s.replace(pos, f.size(), t), // replace with t pos = s.find(f, pos + t.size()) // find next occurrence of f @@ -9266,7 +9222,7 @@ class basic_json else { // make sure the top element of the pointer exists - json_pointer top_pointer = ptr.top(); + auto top_pointer = ptr.top(); if (top_pointer != ptr) { basic_json& x = result.at(top_pointer); @@ -9674,7 +9630,7 @@ namespace std @since version 1.0.0 */ -template <> +template<> inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( is_nothrow_move_constructible::value and @@ -9685,7 +9641,7 @@ inline void swap(nlohmann::json& j1, } /// hash value for JSON objects -template <> +template<> struct hash { /*! diff --git a/test/src/unit-class_const_iterator.cpp b/test/src/unit-class_const_iterator.cpp index 4908b5ce..b64e7e3c 100644 --- a/test/src/unit-class_const_iterator.cpp +++ b/test/src/unit-class_const_iterator.cpp @@ -64,6 +64,22 @@ TEST_CASE("const_iterator class") json::const_iterator it2(&j); 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") diff --git a/test/src/unit-deserialization.cpp b/test/src/unit-deserialization.cpp index 78188574..9d4c064f 100644 --- a/test/src/unit-deserialization.cpp +++ b/test/src/unit-deserialization.cpp @@ -33,41 +33,87 @@ using nlohmann::json; TEST_CASE("deserialization") { - SECTION("stream") + SECTION("successful deserialization") { - std::stringstream ss; - ss << "[\"foo\",1,2,3,false,{\"one\":1}]"; - json j = json::parse(ss); - CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}})); + SECTION("stream") + { + std::stringstream ss; + 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") + { + 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") + SECTION("successful deserialization") { - 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("stream") + { + 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("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("string") + { + json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}"; + CHECK_THROWS_AS(json::parse(s), std::invalid_argument); + CHECK_THROWS_WITH(json::parse(s), "parse error - unexpected end of input; expected ']'"); + } - 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("operator<<") + { + std::stringstream ss; + ss << "[\"foo\",1,2,3,false,{\"one\":1}"; + json j; + CHECK_THROWS_AS(j << ss, std::invalid_argument); + CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input"); + } - SECTION("user-defined string literal") - { - CHECK("[\"foo\",1,2,3,false,{\"one\":1}]"_json == json({"foo", 1, 2, 3, false, {{"one", 1}}})); + SECTION("operator>>") + { + std::stringstream ss; + ss << "[\"foo\",1,2,3,false,{\"one\":1}"; + json j; + CHECK_THROWS_AS(ss >> j, std::invalid_argument); + CHECK_THROWS_WITH(ss >> j, "parse error - unexpected end of input"); + } + + SECTION("user-defined string literal") + { + 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 ']'"); + } } } From 941714c99c0ab9150b6ca3e451c8d2ffcafe0be3 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 30 Aug 2016 23:49:06 +0200 Subject: [PATCH 3/5] template changes did not work with MSVC --- src/json.hpp.re2c | 218 ++++++++++++++++++++++++++++------------------ 1 file changed, 131 insertions(+), 87 deletions(-) diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 28532a8d..75fc27e5 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -1164,10 +1164,11 @@ class basic_json @since version 1.0.0 */ - template::value and - std::is_constructible::value, int>::type - = 0> + template ::value and + std::is_constructible::value, int>::type + = 0> basic_json(const CompatibleObjectType& val) : m_type(value_t::object) { @@ -1228,15 +1229,16 @@ class basic_json @since version 1.0.0 */ - template::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - std::is_constructible::value, int>::type - = 0> + template ::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + std::is_constructible::value, int>::type + = 0> basic_json(const CompatibleArrayType& val) : m_type(value_t::array) { @@ -1322,9 +1324,10 @@ class basic_json @since version 1.0.0 */ - template::value, int>::type - = 0> + template ::value, int>::type + = 0> basic_json(const CompatibleStringType& val) : basic_json(string_t(val)) { @@ -1374,7 +1377,8 @@ class basic_json @since version 1.0.0 */ - template::value) and std::is_same::value , int>::type @@ -1473,7 +1477,8 @@ class basic_json @since version 2.0.0 */ - template::value) and std::is_same::value , int>::type @@ -1504,11 +1509,13 @@ class basic_json @since version 2.0.0 */ - template::value and - std::numeric_limits::is_integer and - not std::numeric_limits::is_signed, CompatibleNumberUnsignedType>::type - = 0> + template ::value and + std::numeric_limits::is_integer and + not std::numeric_limits::is_signed, + CompatibleNumberUnsignedType>::type + = 0> basic_json(const CompatibleNumberUnsignedType val) noexcept : m_type(value_t::number_unsigned), m_value(static_cast(val)) @@ -1584,9 +1591,11 @@ class basic_json @since version 1.0.0 */ - template::value and - std::is_floating_point::value>::type> + std::is_floating_point::value>::type + > basic_json(const CompatibleNumberFloatType val) noexcept : basic_json(number_float_t(val)) { @@ -1663,8 +1672,8 @@ class basic_json @since version 1.0.0 */ basic_json(std::initializer_list init, - const bool type_deduction = true, - const value_t manual_type = value_t::array) + bool type_deduction = true, + value_t manual_type = value_t::array) { // check if each element is an array with two elements whose first // element is a string @@ -1853,9 +1862,12 @@ class basic_json @since version 1.0.0 */ - template::value or - std::is_same::value>::type> + template ::value or + std::is_same::value + , int>::type + = 0> basic_json(InputIT first, InputIT last) { assert(first.m_object != nullptr); @@ -2604,10 +2616,11 @@ class basic_json ////////////////// /// get an object (explicit) - template::value and - std::is_convertible::value - , int>::type = 0> + template ::value and + std::is_convertible::value + , int>::type = 0> T get_impl(T*) const { if (is_object()) @@ -2634,13 +2647,14 @@ class basic_json } /// get an array (explicit) - template::value and - not std::is_same::value and - not std::is_arithmetic::value and - not std::is_convertible::value and - not has_mapped_type::value - , int>::type = 0> + template ::value and + not std::is_same::value and + not std::is_arithmetic::value and + not std::is_convertible::value and + not has_mapped_type::value + , int>::type = 0> T get_impl(T*) const { if (is_array()) @@ -2660,10 +2674,11 @@ class basic_json } /// get an array (explicit) - template::value and - not std::is_same::value - , int>::type = 0> + template ::value and + not std::is_same::value + , int>::type = 0> std::vector get_impl(std::vector*) const { if (is_array()) @@ -2684,10 +2699,11 @@ class basic_json } /// get an array (explicit) - template::value and - not has_mapped_type::value - , int>::type = 0> + template ::value and + not has_mapped_type::value + , int>::type = 0> T get_impl(T*) const { if (is_array()) @@ -2714,9 +2730,10 @@ class basic_json } /// get a string (explicit) - template::value - , int>::type = 0> + template ::value + , int>::type = 0> T get_impl(T*) const { if (is_string()) @@ -2730,8 +2747,10 @@ class basic_json } /// get a number (explicit) - template::value, int>::type = 0> + template::value + , int>::type = 0> T get_impl(T*) const { switch (m_type) @@ -2920,8 +2939,10 @@ class basic_json @since version 1.0.0 */ - template::value>::type> + template::value + , int>::type = 0> ValueType get() const { return get_impl(static_cast(nullptr)); @@ -2954,8 +2975,10 @@ class basic_json @since version 1.0.0 */ - template::value>::type> + template::value + , int>::type = 0> PointerType get() noexcept { // delegate the call to get_ptr @@ -2966,8 +2989,10 @@ class basic_json @brief get a pointer value (explicit) @copydoc get() */ - template::value>::type> + template::value + , int>::type = 0> constexpr const PointerType get() const noexcept { // delegate the call to get_ptr @@ -3000,8 +3025,10 @@ class basic_json @since version 1.0.0 */ - template::value>::type> + template::value + , int>::type = 0> PointerType get_ptr() noexcept { // get the type of the PointerType (remove pointer and const) @@ -3027,9 +3054,11 @@ class basic_json @brief get a pointer value (implicit) @copydoc get_ptr() */ - template::value - and std::is_const::type>::value>::type> + and std::is_const::type>::value + , int>::type = 0> constexpr const PointerType get_ptr() const noexcept { // get the type of the PointerType (remove pointer and const) @@ -3077,8 +3106,10 @@ class basic_json @since version 1.1.0 */ - template::value>::type> + template::value + , int>::type = 0> ReferenceType get_ref() { // delegate call to get_ref_impl @@ -3089,9 +3120,11 @@ class basic_json @brief get a reference value (implicit) @copydoc get_ref() */ - template::value - and std::is_const::type>::value>::type> + and std::is_const::type>::value + , int>::type = 0> ReferenceType get_ref() const { // delegate call to get_ref_impl @@ -3126,13 +3159,14 @@ class basic_json @since version 1.0.0 */ - template < typename ValueType, typename = typename std::enable_if < + template < typename ValueType, typename + std::enable_if < not std::is_pointer::value and not std::is_same::value #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 and not std::is_same>::value #endif - >::type > + , int >::type = 0 > operator ValueType() const { // delegate the call to get<>() const @@ -3718,8 +3752,10 @@ class basic_json @since version 1.0.0 */ - template::value>::type> + template ::value + , int>::type = 0> ValueType value(const typename object_t::key_type& key, ValueType default_value) const { // at only works for objects @@ -3792,8 +3828,10 @@ class basic_json @since version 2.0.2 */ - template::value>::type> + template ::value + , int>::type = 0> ValueType value(const json_pointer& ptr, ValueType default_value) const { // at only works for objects @@ -3954,9 +3992,12 @@ class basic_json @since version 1.0.0 */ - template::value or - std::is_same::value>::type> + template ::value or + std::is_same::value + , int>::type + = 0> InteratorType erase(InteratorType pos) { // make sure iterator fits the current value @@ -4060,9 +4101,12 @@ class basic_json @since version 1.0.0 */ - template::value or - std::is_same::value>::type> + template ::value or + std::is_same::value + , int>::type + = 0> InteratorType erase(InteratorType first, InteratorType last) { // make sure iterator fits the current value @@ -6223,7 +6267,7 @@ class basic_json const unsigned int current_indent = 0) const { // variable to hold indentation for recursive calls - auto new_indent = current_indent; + unsigned int new_indent = current_indent; switch (m_type) { @@ -7517,7 +7561,7 @@ class basic_json const std::size_t codepoint2 = 0) { // calculate the code point from the given code points - auto codepoint = codepoint1; + std::size_t codepoint = codepoint1; // check if codepoint1 is a high surrogate if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF) @@ -8777,7 +8821,7 @@ class basic_json auto reference_token = reference_string.substr(start, slash - start); // check reference tokens are properly escaped - for (auto pos = reference_token.find_first_of("~"); + for (size_t pos = reference_token.find_first_of("~"); pos != std::string::npos; pos = reference_token.find_first_of("~", pos + 1)) { @@ -8822,7 +8866,7 @@ class basic_json assert(not f.empty()); for ( - auto pos = s.find(f); // find first occurrence of f + size_t pos = s.find(f); // find first occurrence of f pos != std::string::npos; // make sure f was found s.replace(pos, f.size(), t), // replace with t pos = s.find(f, pos + t.size()) // find next occurrence of f @@ -9222,7 +9266,7 @@ class basic_json else { // make sure the top element of the pointer exists - auto top_pointer = ptr.top(); + json_pointer top_pointer = ptr.top(); if (top_pointer != ptr) { basic_json& x = result.at(top_pointer); @@ -9630,7 +9674,7 @@ namespace std @since version 1.0.0 */ -template<> +template <> inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( is_nothrow_move_constructible::value and @@ -9641,7 +9685,7 @@ inline void swap(nlohmann::json& j1, } /// hash value for JSON objects -template<> +template <> struct hash { /*! From afba1d3fcb8921885b7169f8355a4e472d9b64f2 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 30 Aug 2016 23:51:14 +0200 Subject: [PATCH 4/5] forgot to run re2c --- src/json.hpp | 218 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 131 insertions(+), 87 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index 2f0f02d5..d6f8925f 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -1164,10 +1164,11 @@ class basic_json @since version 1.0.0 */ - template::value and - std::is_constructible::value, int>::type - = 0> + template ::value and + std::is_constructible::value, int>::type + = 0> basic_json(const CompatibleObjectType& val) : m_type(value_t::object) { @@ -1228,15 +1229,16 @@ class basic_json @since version 1.0.0 */ - template::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - std::is_constructible::value, int>::type - = 0> + template ::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + std::is_constructible::value, int>::type + = 0> basic_json(const CompatibleArrayType& val) : m_type(value_t::array) { @@ -1322,9 +1324,10 @@ class basic_json @since version 1.0.0 */ - template::value, int>::type - = 0> + template ::value, int>::type + = 0> basic_json(const CompatibleStringType& val) : basic_json(string_t(val)) { @@ -1374,7 +1377,8 @@ class basic_json @since version 1.0.0 */ - template::value) and std::is_same::value , int>::type @@ -1473,7 +1477,8 @@ class basic_json @since version 2.0.0 */ - template::value) and std::is_same::value , int>::type @@ -1504,11 +1509,13 @@ class basic_json @since version 2.0.0 */ - template::value and - std::numeric_limits::is_integer and - not std::numeric_limits::is_signed, CompatibleNumberUnsignedType>::type - = 0> + template ::value and + std::numeric_limits::is_integer and + not std::numeric_limits::is_signed, + CompatibleNumberUnsignedType>::type + = 0> basic_json(const CompatibleNumberUnsignedType val) noexcept : m_type(value_t::number_unsigned), m_value(static_cast(val)) @@ -1584,9 +1591,11 @@ class basic_json @since version 1.0.0 */ - template::value and - std::is_floating_point::value>::type> + std::is_floating_point::value>::type + > basic_json(const CompatibleNumberFloatType val) noexcept : basic_json(number_float_t(val)) { @@ -1663,8 +1672,8 @@ class basic_json @since version 1.0.0 */ basic_json(std::initializer_list init, - const bool type_deduction = true, - const value_t manual_type = value_t::array) + bool type_deduction = true, + value_t manual_type = value_t::array) { // check if each element is an array with two elements whose first // element is a string @@ -1853,9 +1862,12 @@ class basic_json @since version 1.0.0 */ - template::value or - std::is_same::value>::type> + template ::value or + std::is_same::value + , int>::type + = 0> basic_json(InputIT first, InputIT last) { assert(first.m_object != nullptr); @@ -2604,10 +2616,11 @@ class basic_json ////////////////// /// get an object (explicit) - template::value and - std::is_convertible::value - , int>::type = 0> + template ::value and + std::is_convertible::value + , int>::type = 0> T get_impl(T*) const { if (is_object()) @@ -2634,13 +2647,14 @@ class basic_json } /// get an array (explicit) - template::value and - not std::is_same::value and - not std::is_arithmetic::value and - not std::is_convertible::value and - not has_mapped_type::value - , int>::type = 0> + template ::value and + not std::is_same::value and + not std::is_arithmetic::value and + not std::is_convertible::value and + not has_mapped_type::value + , int>::type = 0> T get_impl(T*) const { if (is_array()) @@ -2660,10 +2674,11 @@ class basic_json } /// get an array (explicit) - template::value and - not std::is_same::value - , int>::type = 0> + template ::value and + not std::is_same::value + , int>::type = 0> std::vector get_impl(std::vector*) const { if (is_array()) @@ -2684,10 +2699,11 @@ class basic_json } /// get an array (explicit) - template::value and - not has_mapped_type::value - , int>::type = 0> + template ::value and + not has_mapped_type::value + , int>::type = 0> T get_impl(T*) const { if (is_array()) @@ -2714,9 +2730,10 @@ class basic_json } /// get a string (explicit) - template::value - , int>::type = 0> + template ::value + , int>::type = 0> T get_impl(T*) const { if (is_string()) @@ -2730,8 +2747,10 @@ class basic_json } /// get a number (explicit) - template::value, int>::type = 0> + template::value + , int>::type = 0> T get_impl(T*) const { switch (m_type) @@ -2920,8 +2939,10 @@ class basic_json @since version 1.0.0 */ - template::value>::type> + template::value + , int>::type = 0> ValueType get() const { return get_impl(static_cast(nullptr)); @@ -2954,8 +2975,10 @@ class basic_json @since version 1.0.0 */ - template::value>::type> + template::value + , int>::type = 0> PointerType get() noexcept { // delegate the call to get_ptr @@ -2966,8 +2989,10 @@ class basic_json @brief get a pointer value (explicit) @copydoc get() */ - template::value>::type> + template::value + , int>::type = 0> constexpr const PointerType get() const noexcept { // delegate the call to get_ptr @@ -3000,8 +3025,10 @@ class basic_json @since version 1.0.0 */ - template::value>::type> + template::value + , int>::type = 0> PointerType get_ptr() noexcept { // get the type of the PointerType (remove pointer and const) @@ -3027,9 +3054,11 @@ class basic_json @brief get a pointer value (implicit) @copydoc get_ptr() */ - template::value - and std::is_const::type>::value>::type> + and std::is_const::type>::value + , int>::type = 0> constexpr const PointerType get_ptr() const noexcept { // get the type of the PointerType (remove pointer and const) @@ -3077,8 +3106,10 @@ class basic_json @since version 1.1.0 */ - template::value>::type> + template::value + , int>::type = 0> ReferenceType get_ref() { // delegate call to get_ref_impl @@ -3089,9 +3120,11 @@ class basic_json @brief get a reference value (implicit) @copydoc get_ref() */ - template::value - and std::is_const::type>::value>::type> + and std::is_const::type>::value + , int>::type = 0> ReferenceType get_ref() const { // delegate call to get_ref_impl @@ -3126,13 +3159,14 @@ class basic_json @since version 1.0.0 */ - template < typename ValueType, typename = typename std::enable_if < + template < typename ValueType, typename + std::enable_if < not std::is_pointer::value and not std::is_same::value #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 and not std::is_same>::value #endif - >::type > + , int >::type = 0 > operator ValueType() const { // delegate the call to get<>() const @@ -3718,8 +3752,10 @@ class basic_json @since version 1.0.0 */ - template::value>::type> + template ::value + , int>::type = 0> ValueType value(const typename object_t::key_type& key, ValueType default_value) const { // at only works for objects @@ -3792,8 +3828,10 @@ class basic_json @since version 2.0.2 */ - template::value>::type> + template ::value + , int>::type = 0> ValueType value(const json_pointer& ptr, ValueType default_value) const { // at only works for objects @@ -3954,9 +3992,12 @@ class basic_json @since version 1.0.0 */ - template::value or - std::is_same::value>::type> + template ::value or + std::is_same::value + , int>::type + = 0> InteratorType erase(InteratorType pos) { // make sure iterator fits the current value @@ -4060,9 +4101,12 @@ class basic_json @since version 1.0.0 */ - template::value or - std::is_same::value>::type> + template ::value or + std::is_same::value + , int>::type + = 0> InteratorType erase(InteratorType first, InteratorType last) { // make sure iterator fits the current value @@ -6223,7 +6267,7 @@ class basic_json const unsigned int current_indent = 0) const { // variable to hold indentation for recursive calls - auto new_indent = current_indent; + unsigned int new_indent = current_indent; switch (m_type) { @@ -7517,7 +7561,7 @@ class basic_json const std::size_t codepoint2 = 0) { // calculate the code point from the given code points - auto codepoint = codepoint1; + std::size_t codepoint = codepoint1; // check if codepoint1 is a high surrogate if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF) @@ -9480,7 +9524,7 @@ basic_json_parser_63: auto reference_token = reference_string.substr(start, slash - start); // check reference tokens are properly escaped - for (auto pos = reference_token.find_first_of("~"); + for (size_t pos = reference_token.find_first_of("~"); pos != std::string::npos; pos = reference_token.find_first_of("~", pos + 1)) { @@ -9525,7 +9569,7 @@ basic_json_parser_63: assert(not f.empty()); for ( - auto pos = s.find(f); // find first occurrence of f + size_t pos = s.find(f); // find first occurrence of f pos != std::string::npos; // make sure f was found s.replace(pos, f.size(), t), // replace with t pos = s.find(f, pos + t.size()) // find next occurrence of f @@ -9925,7 +9969,7 @@ basic_json_parser_63: else { // make sure the top element of the pointer exists - auto top_pointer = ptr.top(); + json_pointer top_pointer = ptr.top(); if (top_pointer != ptr) { basic_json& x = result.at(top_pointer); @@ -10333,7 +10377,7 @@ namespace std @since version 1.0.0 */ -template<> +template <> inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( is_nothrow_move_constructible::value and @@ -10344,7 +10388,7 @@ inline void swap(nlohmann::json& j1, } /// hash value for JSON objects -template<> +template <> struct hash { /*! From 442058f8edd62a3a95cb6c8c37c0763877e125e7 Mon Sep 17 00:00:00 2001 From: Niels Date: Wed, 31 Aug 2016 17:07:35 +0200 Subject: [PATCH 5/5] interface cleanup --- doc/examples/basic_json.cpp | 12 ----- doc/examples/basic_json.link | 1 - doc/examples/basic_json.output | 1 - doc/examples/basic_json__istream.cpp | 4 +- doc/examples/basic_json__istream.link | 2 +- doc/examples/basic_json__nullptr_t.cpp | 9 ++-- doc/examples/basic_json__nullptr_t.link | 2 +- doc/examples/basic_json__nullptr_t.output | 1 + src/json.hpp | 65 +++++++++-------------- src/json.hpp.re2c | 65 +++++++++-------------- 10 files changed, 62 insertions(+), 100 deletions(-) delete mode 100644 doc/examples/basic_json.cpp delete mode 100644 doc/examples/basic_json.link delete mode 100644 doc/examples/basic_json.output diff --git a/doc/examples/basic_json.cpp b/doc/examples/basic_json.cpp deleted file mode 100644 index 0f36e4f8..00000000 --- a/doc/examples/basic_json.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include - -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'; -} diff --git a/doc/examples/basic_json.link b/doc/examples/basic_json.link deleted file mode 100644 index e5c17c93..00000000 --- a/doc/examples/basic_json.link +++ /dev/null @@ -1 +0,0 @@ -online \ No newline at end of file diff --git a/doc/examples/basic_json.output b/doc/examples/basic_json.output deleted file mode 100644 index 19765bd5..00000000 --- a/doc/examples/basic_json.output +++ /dev/null @@ -1 +0,0 @@ -null diff --git a/doc/examples/basic_json__istream.cpp b/doc/examples/basic_json__istream.cpp index 71f16ed3..32885b22 100644 --- a/doc/examples/basic_json__istream.cpp +++ b/doc/examples/basic_json__istream.cpp @@ -27,7 +27,8 @@ int main() ss << text; // 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"; @@ -51,5 +52,6 @@ int main() // create JSON from stream (with callback) json j_filtered(ss, cb); + // shall be replaced by: json j_filtered = json::parse(ss, cb); std::cout << std::setw(4) << j_filtered << '\n'; } \ No newline at end of file diff --git a/doc/examples/basic_json__istream.link b/doc/examples/basic_json__istream.link index 20d1033c..eb165e2f 100644 --- a/doc/examples/basic_json__istream.link +++ b/doc/examples/basic_json__istream.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/basic_json__nullptr_t.cpp b/doc/examples/basic_json__nullptr_t.cpp index 426afabc..d0156d53 100644 --- a/doc/examples/basic_json__nullptr_t.cpp +++ b/doc/examples/basic_json__nullptr_t.cpp @@ -4,9 +4,12 @@ using json = nlohmann::json; int main() { - // create a JSON null value - json j(nullptr); + // implicitly create a JSON null value + json j1; + + // explicitly create a JSON null value + json j2(nullptr); // serialize the JSON null value - std::cout << j << '\n'; + std::cout << j1 << '\n' << j2 << '\n'; } diff --git a/doc/examples/basic_json__nullptr_t.link b/doc/examples/basic_json__nullptr_t.link index 7e917752..f911caa5 100644 --- a/doc/examples/basic_json__nullptr_t.link +++ b/doc/examples/basic_json__nullptr_t.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/basic_json__nullptr_t.output b/doc/examples/basic_json__nullptr_t.output index 19765bd5..c1e4b6c1 100644 --- a/doc/examples/basic_json__nullptr_t.output +++ b/doc/examples/basic_json__nullptr_t.output @@ -1 +1,2 @@ null +null diff --git a/src/json.hpp b/src/json.hpp index d6f8925f..d755f712 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -73,6 +73,15 @@ SOFTWARE. #pragma GCC diagnostic ignored "-Wfloat-equal" #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 @see https://github.com/nlohmann @@ -1057,40 +1066,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` - value constructor as it takes no parameters. - - @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. + Create a `null` JSON value. It either takes a null pointer as parameter + (explicitly creating `null`) or no parameter (implicitly creating `null`). The passed null pointer itself is not read -- it is only used to choose the right constructor. @@ -1099,15 +1078,12 @@ class basic_json @exceptionsafety No-throw guarantee: this constructor never throws exceptions. - @liveexample{The following code shows the constructor with null pointer - parameter.,basic_json__nullptr_t} - - @sa @ref basic_json() -- default constructor (implicitly creating a `null` - value) + @liveexample{The following code shows the constructor with and without a + null pointer parameter.,basic_json__nullptr_t} @since version 1.0.0 */ - basic_json(std::nullptr_t) noexcept + basic_json(std::nullptr_t = nullptr) noexcept : basic_json(value_t::null) { assert_invariant(); @@ -1971,12 +1947,21 @@ class basic_json @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 a `std::stringstream` with and without callback 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) { *this = parser(i, cb).parse(); diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 75fc27e5..75b38d96 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -73,6 +73,15 @@ SOFTWARE. #pragma GCC diagnostic ignored "-Wfloat-equal" #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 @see https://github.com/nlohmann @@ -1057,40 +1066,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` - value constructor as it takes no parameters. - - @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. + Create a `null` JSON value. It either takes a null pointer as parameter + (explicitly creating `null`) or no parameter (implicitly creating `null`). The passed null pointer itself is not read -- it is only used to choose the right constructor. @@ -1099,15 +1078,12 @@ class basic_json @exceptionsafety No-throw guarantee: this constructor never throws exceptions. - @liveexample{The following code shows the constructor with null pointer - parameter.,basic_json__nullptr_t} - - @sa @ref basic_json() -- default constructor (implicitly creating a `null` - value) + @liveexample{The following code shows the constructor with and without a + null pointer parameter.,basic_json__nullptr_t} @since version 1.0.0 */ - basic_json(std::nullptr_t) noexcept + basic_json(std::nullptr_t = nullptr) noexcept : basic_json(value_t::null) { assert_invariant(); @@ -1971,12 +1947,21 @@ class basic_json @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 a `std::stringstream` with and without callback 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) { *this = parser(i, cb).parse();