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")