diff --git a/Makefile b/Makefile index 38d40eda..179df3aa 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,7 @@ doctest: # -Wno-documentation-unknown-command: code uses user-defined commands like @complexity # -Wno-exit-time-destructors: warning in Catch code # -Wno-keyword-macro: unit-tests use "#define private public" +# -Wno-deprecated-declarations: the library deprecated some functions # -Wno-weak-vtables: exception class is defined inline, but has virtual method # -Wno-range-loop-analysis: iterator_wrapper tests tests "for(const auto i...)" pedantic_clang: @@ -55,6 +56,7 @@ pedantic_clang: -Wno-documentation-unknown-command \ -Wno-exit-time-destructors \ -Wno-keyword-macro \ + -Wno-deprecated-declarations \ -Wno-weak-vtables \ -Wno-range-loop-analysis" @@ -62,6 +64,7 @@ pedantic_clang: pedantic_gcc: $(MAKE) json_unit CXX=g++ CXXFLAGS="\ -std=c++11 \ + -Wno-deprecated-declarations \ -Werror \ -Wall -Wpedantic -Wextra \ -Walloca \ diff --git a/src/json.hpp b/src/json.hpp index 5fab7d25..903f3178 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -79,6 +79,15 @@ SOFTWARE. #pragma GCC diagnostic ignored "-Wdocumentation" #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 + // allow to disable exceptions #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && not defined(JSON_NOEXCEPTION) #define JSON_THROW(exception) throw exception @@ -7093,8 +7102,12 @@ class basic_json /*! @brief serialize to stream - @copydoc operator<<(std::ostream&, const basic_json&) + @deprecated This stream operator is deprecated and will be removed in a + future version of the library. Please use + @ref std::ostream& operator<<(std::ostream&, const basic_json&) + instead; that is, replace calls like `j >> o;` with `o << j;`. */ + JSON_DEPRECATED friend std::ostream& operator>>(const basic_json& j, std::ostream& o) { return o << j; @@ -7367,6 +7380,20 @@ class basic_json return parse(std::begin(c), std::end(c), cb); } + /*! + @brief deserialize from stream + @deprecated This stream operator is deprecated and will be removed in a + future version of the library. Please use + @ref std::istream& operator>>(std::istream&, basic_json&) + instead; that is, replace calls like `j << i;` with `i >> j;`. + */ + JSON_DEPRECATED + friend std::istream& operator<<(basic_json& j, std::istream& i) + { + j = parser(i).parse(); + return i; + } + /*! @brief deserialize from stream @@ -7393,16 +7420,6 @@ class basic_json @since version 1.0.0 */ - friend std::istream& operator<<(basic_json& j, std::istream& i) - { - j = parser(i).parse(false); - return i; - } - - /*! - @brief deserialize from stream - @copydoc operator<<(basic_json&, std::istream&) - */ friend std::istream& operator>>(std::istream& i, basic_json& j) { j = parser(i).parse(false); @@ -13259,5 +13276,6 @@ inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std #undef JSON_TRY #undef JSON_LIKELY #undef JSON_UNLIKELY +#undef JSON_DEPRECATED #endif diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp index d57cb387..e8eae0f8 100644 --- a/test/src/unit-regression.cpp +++ b/test/src/unit-regression.cpp @@ -217,6 +217,7 @@ TEST_CASE("regression tests") json a = {1, 2, 3}; json::reverse_iterator rit = ++a.rbegin(); CHECK(*rit == json(2)); + CHECK(rit.value() == json(2)); } { json a = {1, 2, 3}; @@ -541,7 +542,7 @@ TEST_CASE("regression tests") CAPTURE(filename); json j; std::ifstream f(filename); - CHECK_NOTHROW(j << f); + CHECK_NOTHROW(f >> j); } } @@ -557,7 +558,7 @@ TEST_CASE("regression tests") CAPTURE(filename); json j; std::ifstream f(filename); - CHECK_NOTHROW(j << f); + CHECK_NOTHROW(f >> j); } } @@ -587,15 +588,15 @@ TEST_CASE("regression tests") std::stringstream ss; json j; ss << "123"; - CHECK_NOTHROW(j << ss); + CHECK_NOTHROW(ss >> j); // see https://github.com/nlohmann/json/issues/367#issuecomment-262841893: // ss is not at EOF; this yielded an error before the fix // (threw basic_string::append). No, it should just throw // a parse error because of the EOF. - CHECK_THROWS_AS(j << ss, json::parse_error); - CHECK_THROWS_WITH(j << ss, - "[json.exception.parse_error.101] parse error at 1: syntax error - unexpected end of input"); + CHECK_THROWS_AS(ss >> j, json::parse_error); + CHECK_THROWS_WITH(ss >> j, + "[json.exception.parse_error.101] parse error at 1: parse error - unexpected end of input"); } SECTION("issue #389 - Integer-overflow (OSS-Fuzz issue 267)") diff --git a/test/src/unit-testsuites.cpp b/test/src/unit-testsuites.cpp index b0c721d2..798bc5c7 100644 --- a/test/src/unit-testsuites.cpp +++ b/test/src/unit-testsuites.cpp @@ -78,7 +78,8 @@ TEST_CASE("compliance tests from json.org") { CAPTURE(filename); std::ifstream f(filename); - CHECK_THROWS_AS(json::parse(f), json::parse_error); + json j; + CHECK_THROWS_AS(f >> j, json::parse_error); } } @@ -93,7 +94,8 @@ TEST_CASE("compliance tests from json.org") { CAPTURE(filename); std::ifstream f(filename); - CHECK_NOTHROW(json::parse(f)); + json j; + CHECK_NOTHROW(f >> j); } } } @@ -318,7 +320,7 @@ TEST_CASE("test suite from json-test-suite") // strings in a JSON array std::ifstream f("test/data/json_testsuite/sample.json"); json j; - CHECK_NOTHROW(j = json::parse(f)); + CHECK_NOTHROW(f >> j); // the array has 3 elements CHECK(j.size() == 3); @@ -332,31 +334,36 @@ TEST_CASE("json.org examples") SECTION("1.json") { std::ifstream f("test/data/json.org/1.json"); - CHECK_NOTHROW(json::parse(f)); + json j; + CHECK_NOTHROW(f >> j); } SECTION("2.json") { std::ifstream f("test/data/json.org/2.json"); - CHECK_NOTHROW(json::parse(f)); + json j; + CHECK_NOTHROW(f >> j); } SECTION("3.json") { std::ifstream f("test/data/json.org/3.json"); - CHECK_NOTHROW(json::parse(f)); + json j; + CHECK_NOTHROW(f >> j); } SECTION("4.json") { std::ifstream f("test/data/json.org/4.json"); - CHECK_NOTHROW(json::parse(f)); + json j; + CHECK_NOTHROW(f >> j); } SECTION("5.json") { std::ifstream f("test/data/json.org/5.json"); - CHECK_NOTHROW(json::parse(f)); + json j; + CHECK_NOTHROW(f >> j); } } @@ -538,7 +545,8 @@ TEST_CASE("nst's JSONTestSuite") { CAPTURE(filename); std::ifstream f(filename); - CHECK_NOTHROW(json::parse(f)); + json j; + CHECK_NOTHROW(f >> j); } } @@ -746,7 +754,8 @@ TEST_CASE("nst's JSONTestSuite") { CAPTURE(filename); std::ifstream f(filename); - CHECK_THROWS_AS(json::parse(f), json::parse_error); + json j; + CHECK_THROWS_AS(f >> j, json::parse_error); } } @@ -768,7 +777,8 @@ TEST_CASE("nst's JSONTestSuite") { CAPTURE(filename); std::ifstream f(filename); - CHECK_NOTHROW(json::parse(f)); + json j; + CHECK_NOTHROW(f >> j); } } @@ -787,7 +797,8 @@ TEST_CASE("nst's JSONTestSuite") { CAPTURE(filename); std::ifstream f(filename); - CHECK_THROWS_AS(json::parse(f), json::out_of_range); + json j; + CHECK_THROWS_AS(f >> j, json::out_of_range); } } @@ -813,7 +824,8 @@ TEST_CASE("nst's JSONTestSuite") { CAPTURE(filename); std::ifstream f(filename); - CHECK_THROWS_AS(json::parse(f), json::parse_error); + json j; + CHECK_THROWS_AS(f >> j, json::parse_error); } } } @@ -839,7 +851,8 @@ TEST_CASE("Big List of Naughty Strings") SECTION("parsing blns.json") { std::ifstream f("test/data/big-list-of-naughty-strings/blns.json"); - CHECK_NOTHROW(json::parse(f)); + json j; + CHECK_NOTHROW(f >> j); } // check if parsed strings roundtrip diff --git a/test/src/unit-unicode.cpp b/test/src/unit-unicode.cpp index 805e4c23..9fff61af 100644 --- a/test/src/unit-unicode.cpp +++ b/test/src/unit-unicode.cpp @@ -127,7 +127,7 @@ TEST_CASE("Unicode", "[hide]") // strings in a JSON array std::ifstream f("test/data/json_nlohmann_tests/all_unicode.json"); json j; - CHECK_NOTHROW(j << f); + CHECK_NOTHROW(f >> j); // the array has 1112064 + 1 elemnts (a terminating "null" value) // Note: 1112064 = 0x1FFFFF code points - 2048 invalid values between @@ -170,7 +170,7 @@ TEST_CASE("Unicode", "[hide]") // read a file with a UTF-8 BOM std::ifstream f("test/data/json_nlohmann_tests/bom.json"); json j; - CHECK_NOTHROW(j << f); + CHECK_NOTHROW(f >> j); } SECTION("error for incomplete/wrong BOM")