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 <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';
-}
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 @@
-<a target="_blank" href="http://melpon.org/wandbox/permlink/dRptmFmhvpsYB49t"><b>online</b></a>
\ 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 @@
-<a target="_blank" href="http://melpon.org/wandbox/permlink/VzSqLszbnoWE92dD"><b>online</b></a>
\ No newline at end of file
+<a target="_blank" href="http://melpon.org/wandbox/permlink/R6dzpKXlxrttShf7"><b>online</b></a>
\ 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 @@
-<a target="_blank" href="http://melpon.org/wandbox/permlink/PMMpoM0ujdJDsuta"><b>online</b></a>
\ No newline at end of file
+<a target="_blank" href="http://melpon.org/wandbox/permlink/9Tvfs2dJBW8m8ihA"><b>online</b></a>
\ 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 8ac262e6..1a07e46c 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -74,6 +74,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
@@ -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`
-    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.
 
@@ -1100,15 +1079,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();
@@ -1951,12 +1927,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 3b676458..300337a2 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -74,6 +74,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
@@ -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`
-    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.
 
@@ -1100,15 +1079,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();
@@ -1951,12 +1927,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/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-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));
diff --git a/test/src/unit-deserialization.cpp b/test/src/unit-deserialization.cpp
index dcd7c272..49ae7b4b 100644
--- a/test/src/unit-deserialization.cpp
+++ b/test/src/unit-deserialization.cpp
@@ -35,49 +35,95 @@ 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 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}]";
-        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("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("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;
-        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;
+            CHECK_THROWS_AS(j << ss, std::invalid_argument);
+            CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input");
+        }
 
-    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(ss >> j, std::invalid_argument);
+            CHECK_THROWS_WITH(ss >> j, "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("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 ']'");
+        }
     }
 
     SECTION("contiguous containers")