Merge branch 'feature/detect_unsupported_compilers' into develop

- added error macros to exclude unsupported compilers
diff --git a/README.md b/README.md
index 4ad4037..f6b8408 100644
--- a/README.md
+++ b/README.md
@@ -485,6 +485,7 @@
 - [Tom Needham](https://github.com/06needhamt) fixed a subtle bug with MSVC 2015 which was also proposed by [Michael K.](https://github.com/Epidal).
 - [Mário Feroldi](https://github.com/thelostt) fixed a small typo.
 - [duncanwerner](https://github.com/duncanwerner) found a really embarrassing performance regression in the 2.0.0 release.
+- [Damien](https://github.com/dtoma) fixed one of the last conversion warnings.
 
 Thanks a lot for helping out!
 
diff --git a/src/json.hpp b/src/json.hpp
index d73abe0..4d5e9dd 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -46,6 +46,7 @@
 #include <limits>
 #include <map>
 #include <memory>
+#include <numeric>
 #include <sstream>
 #include <stdexcept>
 #include <string>
@@ -1567,22 +1568,13 @@
                bool type_deduction = true,
                value_t manual_type = value_t::array)
     {
-        // the initializer list could describe an object
-        bool is_an_object = true;
-
         // check if each element is an array with two elements whose first
         // element is a string
-        for (const auto& element : init)
+        bool is_an_object = std::all_of(init.begin(), init.end(),
+                                        [](const basic_json & element)
         {
-            if (not element.is_array() or element.size() != 2
-                    or not element[0].is_string())
-            {
-                // we found an element that makes it impossible to use the
-                // initializer list as object
-                is_an_object = false;
-                break;
-            }
-        }
+            return element.is_array() and element.size() == 2 and element[0].is_string();
+        });
 
         // adjust type if type deduction is not wanted
         if (not type_deduction)
@@ -1608,10 +1600,10 @@
 
             assert(m_value.object != nullptr);
 
-            for (auto& element : init)
+            std::for_each(init.begin(), init.end(), [this](const basic_json & element)
             {
                 m_value.object->emplace(*(element[0].m_value.string), element[1]);
-            }
+            });
         }
         else
         {
@@ -3248,11 +3240,13 @@
         // operator[] only works for arrays
         if (is_array())
         {
-            // fill up array with null values until given idx is reached
+            // fill up array with null values if given idx is outside range
             assert(m_value.array != nullptr);
-            for (size_t i = m_value.array->size(); i <= idx; ++i)
+            if (idx >= m_value.array->size())
             {
-                m_value.array->push_back(basic_json());
+                m_value.array->insert(m_value.array->end(),
+                                      idx - m_value.array->size() + 1,
+                                      basic_json());
             }
 
             return m_value.array->operator[](idx);
@@ -5814,7 +5808,7 @@
     ///////////////////////////
 
     /// return the type as string
-    string_t type_name() const noexcept
+    std::string type_name() const
     {
         switch (m_type)
         {
@@ -5845,9 +5839,8 @@
     */
     static std::size_t extra_space(const string_t& s) noexcept
     {
-        std::size_t result = 0;
-
-        for (const auto& c : s)
+        return std::accumulate(s.begin(), s.end(), size_t{},
+                               [](size_t res, typename string_t::value_type c)
         {
             switch (c)
             {
@@ -5860,8 +5853,7 @@
                 case '\t':
                 {
                     // from c (1 byte) to \x (2 bytes)
-                    result += 1;
-                    break;
+                    return res + 1;
                 }
 
                 default:
@@ -5869,14 +5861,15 @@
                     if (c >= 0x00 and c <= 0x1f)
                     {
                         // from c (1 byte) to \uxxxx (6 bytes)
-                        result += 5;
+                        return res + 5;
                     }
-                    break;
+                    else
+                    {
+                        return res;
+                    }
                 }
             }
-        }
-
-        return result;
+        });
     }
 
     /*!
@@ -5970,16 +5963,15 @@
                     {
                         // convert a number 0..15 to its hex representation
                         // (0..f)
-                        const auto hexify = [](const int v) -> char
+                        static const char hexify[16] =
                         {
-                            return (v < 10)
-                            ? ('0' + static_cast<char>(v))
-                            : ('a' + static_cast<char>((v - 10) & 0x1f));
+                            '0', '1', '2', '3', '4', '5', '6', '7',
+                            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
                         };
 
                         // print character c as \uxxxx
                         for (const char m :
-                    { 'u', '0', '0', hexify(c >> 4), hexify(c & 0x0f)
+                    { 'u', '0', '0', hexify[c >> 4], hexify[c & 0x0f]
                         })
                         {
                             result[++pos] = m;
@@ -6626,13 +6618,13 @@
             {
                 case basic_json::value_t::object:
                 {
-                    ++m_it.object_iterator;
+                    std::advance(m_it.object_iterator, 1);
                     break;
                 }
 
                 case basic_json::value_t::array:
                 {
-                    ++m_it.array_iterator;
+                    std::advance(m_it.array_iterator, 1);
                     break;
                 }
 
@@ -6663,13 +6655,13 @@
             {
                 case basic_json::value_t::object:
                 {
-                    --m_it.object_iterator;
+                    std::advance(m_it.object_iterator, -1);
                     break;
                 }
 
                 case basic_json::value_t::array:
                 {
-                    --m_it.array_iterator;
+                    std::advance(m_it.array_iterator, -1);
                     break;
                 }
 
@@ -6781,7 +6773,7 @@
 
                 case basic_json::value_t::array:
                 {
-                    m_it.array_iterator += i;
+                    std::advance(m_it.array_iterator, i);
                     break;
                 }
 
@@ -6855,7 +6847,7 @@
 
                 case basic_json::value_t::array:
                 {
-                    return *(m_it.array_iterator + n);
+                    return *std::next(m_it.array_iterator, n);
                 }
 
                 case basic_json::value_t::null:
@@ -8791,14 +8783,12 @@
         */
         std::string to_string() const noexcept
         {
-            std::string result;
-
-            for (const auto& reference_token : reference_tokens)
+            return std::accumulate(reference_tokens.begin(),
+                                   reference_tokens.end(), std::string{},
+                                   [](const std::string & a, const std::string & b)
             {
-                result += "/" + escape(reference_token);
-            }
-
-            return result;
+                return a + "/" + escape(b);
+            });
         }
 
         /// @copydoc to_string()
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 2d57325..7441e29 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -46,6 +46,7 @@
 #include <limits>
 #include <map>
 #include <memory>
+#include <numeric>
 #include <sstream>
 #include <stdexcept>
 #include <string>
@@ -1567,22 +1568,13 @@
                bool type_deduction = true,
                value_t manual_type = value_t::array)
     {
-        // the initializer list could describe an object
-        bool is_an_object = true;
-
         // check if each element is an array with two elements whose first
         // element is a string
-        for (const auto& element : init)
+        bool is_an_object = std::all_of(init.begin(), init.end(),
+                                        [](const basic_json & element)
         {
-            if (not element.is_array() or element.size() != 2
-                    or not element[0].is_string())
-            {
-                // we found an element that makes it impossible to use the
-                // initializer list as object
-                is_an_object = false;
-                break;
-            }
-        }
+            return element.is_array() and element.size() == 2 and element[0].is_string();
+        });
 
         // adjust type if type deduction is not wanted
         if (not type_deduction)
@@ -1608,10 +1600,10 @@
 
             assert(m_value.object != nullptr);
 
-            for (auto& element : init)
+            std::for_each(init.begin(), init.end(), [this](const basic_json & element)
             {
                 m_value.object->emplace(*(element[0].m_value.string), element[1]);
-            }
+            });
         }
         else
         {
@@ -3248,11 +3240,13 @@
         // operator[] only works for arrays
         if (is_array())
         {
-            // fill up array with null values until given idx is reached
+            // fill up array with null values if given idx is outside range
             assert(m_value.array != nullptr);
-            for (size_t i = m_value.array->size(); i <= idx; ++i)
+            if (idx >= m_value.array->size())
             {
-                m_value.array->push_back(basic_json());
+                m_value.array->insert(m_value.array->end(),
+                                      idx - m_value.array->size() + 1,
+                                      basic_json());
             }
 
             return m_value.array->operator[](idx);
@@ -5814,7 +5808,7 @@
     ///////////////////////////
 
     /// return the type as string
-    string_t type_name() const noexcept
+    std::string type_name() const
     {
         switch (m_type)
         {
@@ -5845,9 +5839,8 @@
     */
     static std::size_t extra_space(const string_t& s) noexcept
     {
-        std::size_t result = 0;
-
-        for (const auto& c : s)
+        return std::accumulate(s.begin(), s.end(), size_t{},
+                               [](size_t res, typename string_t::value_type c)
         {
             switch (c)
             {
@@ -5860,8 +5853,7 @@
                 case '\t':
                 {
                     // from c (1 byte) to \x (2 bytes)
-                    result += 1;
-                    break;
+                    return res + 1;
                 }
 
                 default:
@@ -5869,14 +5861,15 @@
                     if (c >= 0x00 and c <= 0x1f)
                     {
                         // from c (1 byte) to \uxxxx (6 bytes)
-                        result += 5;
+                        return res + 5;
                     }
-                    break;
+                    else
+                    {
+                        return res;
+                    }
                 }
             }
-        }
-
-        return result;
+        });
     }
 
     /*!
@@ -5970,16 +5963,15 @@
                     {
                         // convert a number 0..15 to its hex representation
                         // (0..f)
-                        const auto hexify = [](const int v) -> char
+                        static const char hexify[16] =
                         {
-                            return (v < 10)
-                            ? ('0' + static_cast<char>(v))
-                            : ('a' + static_cast<char>((v - 10) & 0x1f));
+                            '0', '1', '2', '3', '4', '5', '6', '7',
+                            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
                         };
 
                         // print character c as \uxxxx
                         for (const char m :
-                    { 'u', '0', '0', hexify(c >> 4), hexify(c & 0x0f)
+                    { 'u', '0', '0', hexify[c >> 4], hexify[c & 0x0f]
                         })
                         {
                             result[++pos] = m;
@@ -6626,13 +6618,13 @@
             {
                 case basic_json::value_t::object:
                 {
-                    ++m_it.object_iterator;
+                    std::advance(m_it.object_iterator, 1);
                     break;
                 }
 
                 case basic_json::value_t::array:
                 {
-                    ++m_it.array_iterator;
+                    std::advance(m_it.array_iterator, 1);
                     break;
                 }
 
@@ -6663,13 +6655,13 @@
             {
                 case basic_json::value_t::object:
                 {
-                    --m_it.object_iterator;
+                    std::advance(m_it.object_iterator, -1);
                     break;
                 }
 
                 case basic_json::value_t::array:
                 {
-                    --m_it.array_iterator;
+                    std::advance(m_it.array_iterator, -1);
                     break;
                 }
 
@@ -6781,7 +6773,7 @@
 
                 case basic_json::value_t::array:
                 {
-                    m_it.array_iterator += i;
+                    std::advance(m_it.array_iterator, i);
                     break;
                 }
 
@@ -6855,7 +6847,7 @@
 
                 case basic_json::value_t::array:
                 {
-                    return *(m_it.array_iterator + n);
+                    return *std::next(m_it.array_iterator, n);
                 }
 
                 case basic_json::value_t::null:
@@ -8101,14 +8093,12 @@
         */
         std::string to_string() const noexcept
         {
-            std::string result;
-
-            for (const auto& reference_token : reference_tokens)
+            return std::accumulate(reference_tokens.begin(),
+                                   reference_tokens.end(), std::string{},
+                                   [](const std::string & a, const std::string & b)
             {
-                result += "/" + escape(reference_token);
-            }
-
-            return result;
+                return a + "/" + escape(b);
+            });
         }
 
         /// @copydoc to_string()
diff --git a/test/src/unit.cpp b/test/src/unit.cpp
index 3b8909a..a12f052 100644
--- a/test/src/unit.cpp
+++ b/test/src/unit.cpp
@@ -10309,252 +10309,261 @@
 TEST_CASE("README", "[hide]")
 {
     {
-        // create an empty structure (null)
-        json j;
-
-        // add a number that is stored as double (note the implicit conversion of j to an object)
-        j["pi"] = 3.141;
-
-        // add a Boolean that is stored as bool
-        j["happy"] = true;
-
-        // add a string that is stored as std::string
-        j["name"] = "Niels";
-
-        // add another null object by passing nullptr
-        j["nothing"] = nullptr;
-
-        // add an object inside the object
-        j["answer"]["everything"] = 42;
-
-        // add an array that is stored as std::vector (using an initializer list)
-        j["list"] = { 1, 0, 2 };
-
-        // add another object (using an initializer list of pairs)
-        j["object"] = { {"currency", "USD"}, {"value", 42.99} };
-
-        // instead, you could also write (which looks very similar to the JSON above)
-        json j2 =
+        // redirect std::cout for the README file
+        auto old_cout_buffer = std::cout.rdbuf();
+        std::ostringstream new_stream;
+        std::cout.rdbuf(new_stream.rdbuf());
         {
-            {"pi", 3.141},
-            {"happy", true},
-            {"name", "Niels"},
-            {"nothing", nullptr},
+            // create an empty structure (null)
+            json j;
+
+            // add a number that is stored as double (note the implicit conversion of j to an object)
+            j["pi"] = 3.141;
+
+            // add a Boolean that is stored as bool
+            j["happy"] = true;
+
+            // add a string that is stored as std::string
+            j["name"] = "Niels";
+
+            // add another null object by passing nullptr
+            j["nothing"] = nullptr;
+
+            // add an object inside the object
+            j["answer"]["everything"] = 42;
+
+            // add an array that is stored as std::vector (using an initializer list)
+            j["list"] = { 1, 0, 2 };
+
+            // add another object (using an initializer list of pairs)
+            j["object"] = { {"currency", "USD"}, {"value", 42.99} };
+
+            // instead, you could also write (which looks very similar to the JSON above)
+            json j2 =
             {
-                "answer", {
-                    {"everything", 42}
+                {"pi", 3.141},
+                {"happy", true},
+                {"name", "Niels"},
+                {"nothing", nullptr},
+                {
+                    "answer", {
+                        {"everything", 42}
+                    }
+                },
+                {"list", {1, 0, 2}},
+                {
+                    "object", {
+                        {"currency", "USD"},
+                        {"value", 42.99}
+                    }
                 }
-            },
-            {"list", {1, 0, 2}},
-            {
-                "object", {
-                    {"currency", "USD"},
-                    {"value", 42.99}
-                }
-            }
-        };
-    }
+            };
+        }
 
-    {
-        // ways to express the empty array []
-        json empty_array_implicit = {{}};
-        json empty_array_explicit = json::array();
+        {
+            // ways to express the empty array []
+            json empty_array_implicit = {{}};
+            json empty_array_explicit = json::array();
 
-        // a way to express the empty object {}
-        json empty_object_explicit = json::object();
+            // a way to express the empty object {}
+            json empty_object_explicit = json::object();
 
-        // a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]]
-        json array_not_object = { json::array({"currency", "USD"}), json::array({"value", 42.99}) };
-    }
+            // a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]]
+            json array_not_object = { json::array({"currency", "USD"}), json::array({"value", 42.99}) };
+        }
 
-    {
-        // create object from string literal
-        json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;
+        {
+            // create object from string literal
+            json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;
 
-        // or even nicer with a raw string literal
-        auto j2 = R"(
+            // or even nicer with a raw string literal
+            auto j2 = R"(
           {
             "happy": true,
             "pi": 3.141
           }
         )"_json;
 
-        // or explicitly
-        auto j3 = json::parse("{ \"happy\": true, \"pi\": 3.141 }");
+            // or explicitly
+            auto j3 = json::parse("{ \"happy\": true, \"pi\": 3.141 }");
 
-        // explicit conversion to string
-        std::string s = j.dump();    // {\"happy\":true,\"pi\":3.141}
+            // explicit conversion to string
+            std::string s = j.dump();    // {\"happy\":true,\"pi\":3.141}
 
-        // serialization with pretty printing
-        // pass in the amount of spaces to indent
-        std::cout << j.dump(4) << std::endl;
-        // {
-        //     "happy": true,
-        //     "pi": 3.141
-        // }
+            // serialization with pretty printing
+            // pass in the amount of spaces to indent
+            std::cout << j.dump(4) << std::endl;
+            // {
+            //     "happy": true,
+            //     "pi": 3.141
+            // }
 
-        std::cout << std::setw(2) << j << std::endl;
-    }
-
-    {
-        // create an array using push_back
-        json j;
-        j.push_back("foo");
-        j.push_back(1);
-        j.push_back(true);
-
-        // iterate the array
-        for (json::iterator it = j.begin(); it != j.end(); ++it)
-        {
-            std::cout << *it << '\n';
+            std::cout << std::setw(2) << j << std::endl;
         }
 
-        // range-based for
-        for (auto element : j)
         {
-            std::cout << element << '\n';
+            // create an array using push_back
+            json j;
+            j.push_back("foo");
+            j.push_back(1);
+            j.push_back(true);
+
+            // iterate the array
+            for (json::iterator it = j.begin(); it != j.end(); ++it)
+            {
+                std::cout << *it << '\n';
+            }
+
+            // range-based for
+            for (auto element : j)
+            {
+                std::cout << element << '\n';
+            }
+
+            // getter/setter
+            const std::string tmp = j[0];
+            j[1] = 42;
+            bool foo = j.at(2);
+
+            // other stuff
+            j.size();     // 3 entries
+            j.empty();    // false
+            j.type();     // json::value_t::array
+            j.clear();    // the array is empty again
+
+            // comparison
+            j == "[\"foo\", 1, true]"_json;  // true
+
+            // create an object
+            json o;
+            o["foo"] = 23;
+            o["bar"] = false;
+            o["baz"] = 3.141;
+
+            // find an entry
+            if (o.find("foo") != o.end())
+            {
+                // there is an entry with key "foo"
+            }
         }
 
-        // getter/setter
-        const std::string tmp = j[0];
-        j[1] = 42;
-        bool foo = j.at(2);
-
-        // other stuff
-        j.size();     // 3 entries
-        j.empty();    // false
-        j.type();     // json::value_t::array
-        j.clear();    // the array is empty again
-
-        // comparison
-        j == "[\"foo\", 1, true]"_json;  // true
-
-        // create an object
-        json o;
-        o["foo"] = 23;
-        o["bar"] = false;
-        o["baz"] = 3.141;
-
-        // find an entry
-        if (o.find("foo") != o.end())
         {
-            // there is an entry with key "foo"
+            std::vector<int> c_vector {1, 2, 3, 4};
+            json j_vec(c_vector);
+            // [1, 2, 3, 4]
+
+            std::deque<float> c_deque {1.2f, 2.3f, 3.4f, 5.6f};
+            json j_deque(c_deque);
+            // [1.2, 2.3, 3.4, 5.6]
+
+            std::list<bool> c_list {true, true, false, true};
+            json j_list(c_list);
+            // [true, true, false, true]
+
+            std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};
+            json j_flist(c_flist);
+            // [12345678909876, 23456789098765, 34567890987654, 45678909876543]
+
+            std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};
+            json j_array(c_array);
+            // [1, 2, 3, 4]
+
+            std::set<std::string> c_set {"one", "two", "three", "four", "one"};
+            json j_set(c_set); // only one entry for "one" is used
+            // ["four", "one", "three", "two"]
+
+            std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"};
+            json j_uset(c_uset); // only one entry for "one" is used
+            // maybe ["two", "three", "four", "one"]
+
+            std::multiset<std::string> c_mset {"one", "two", "one", "four"};
+            json j_mset(c_mset); // only one entry for "one" is used
+            // maybe ["one", "two", "four"]
+
+            std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"};
+            json j_umset(c_umset); // both entries for "one" are used
+            // maybe ["one", "two", "one", "four"]
         }
-    }
 
-    {
-        std::vector<int> c_vector {1, 2, 3, 4};
-        json j_vec(c_vector);
-        // [1, 2, 3, 4]
+        {
+            std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };
+            json j_map(c_map);
+            // {"one": 1, "two": 2, "three": 3}
 
-        std::deque<float> c_deque {1.2f, 2.3f, 3.4f, 5.6f};
-        json j_deque(c_deque);
-        // [1.2, 2.3, 3.4, 5.6]
+            std::unordered_map<const char*, float> c_umap { {"one", 1.2f}, {"two", 2.3f}, {"three", 3.4f} };
+            json j_umap(c_umap);
+            // {"one": 1.2, "two": 2.3, "three": 3.4}
 
-        std::list<bool> c_list {true, true, false, true};
-        json j_list(c_list);
-        // [true, true, false, true]
+            std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
+            json j_mmap(c_mmap); // only one entry for key "three" is used
+            // maybe {"one": true, "two": true, "three": true}
 
-        std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};
-        json j_flist(c_flist);
-        // [12345678909876, 23456789098765, 34567890987654, 45678909876543]
+            std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
+            json j_ummap(c_ummap); // only one entry for key "three" is used
+            // maybe {"one": true, "two": true, "three": true}
+        }
 
-        std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};
-        json j_array(c_array);
-        // [1, 2, 3, 4]
+        {
+            // strings
+            std::string s1 = "Hello, world!";
+            json js = s1;
+            std::string s2 = js;
 
-        std::set<std::string> c_set {"one", "two", "three", "four", "one"};
-        json j_set(c_set); // only one entry for "one" is used
-        // ["four", "one", "three", "two"]
+            // Booleans
+            bool b1 = true;
+            json jb = b1;
+            bool b2 = jb;
 
-        std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"};
-        json j_uset(c_uset); // only one entry for "one" is used
-        // maybe ["two", "three", "four", "one"]
+            // numbers
+            int i = 42;
+            json jn = i;
+            double f = jn;
 
-        std::multiset<std::string> c_mset {"one", "two", "one", "four"};
-        json j_mset(c_mset); // only one entry for "one" is used
-        // maybe ["one", "two", "four"]
+            // etc.
 
-        std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"};
-        json j_umset(c_umset); // both entries for "one" are used
-        // maybe ["one", "two", "one", "four"]
-    }
+            std::string vs = js.get<std::string>();
+            bool vb = jb.get<bool>();
+            int vi = jn.get<int>();
 
-    {
-        std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };
-        json j_map(c_map);
-        // {"one": 1, "two": 2, "three": 3}
+            // etc.
+        }
 
-        std::unordered_map<const char*, float> c_umap { {"one", 1.2f}, {"two", 2.3f}, {"three", 3.4f} };
-        json j_umap(c_umap);
-        // {"one": 1.2, "two": 2.3, "three": 3.4}
-
-        std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
-        json j_mmap(c_mmap); // only one entry for key "three" is used
-        // maybe {"one": true, "two": true, "three": true}
-
-        std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
-        json j_ummap(c_ummap); // only one entry for key "three" is used
-        // maybe {"one": true, "two": true, "three": true}
-    }
-
-    {
-        // strings
-        std::string s1 = "Hello, world!";
-        json js = s1;
-        std::string s2 = js;
-
-        // Booleans
-        bool b1 = true;
-        json jb = b1;
-        bool b2 = jb;
-
-        // numbers
-        int i = 42;
-        json jn = i;
-        double f = jn;
-
-        // etc.
-
-        std::string vs = js.get<std::string>();
-        bool vb = jb.get<bool>();
-        int vi = jn.get<int>();
-
-        // etc.
-    }
-
-    {
-        // a JSON value
-        json j_original = R"({
+        {
+            // a JSON value
+            json j_original = R"({
           "baz": ["one", "two", "three"],
           "foo": "bar"
         })"_json;
 
-        // access members with a JSON pointer (RFC 6901)
-        j_original["/baz/1"_json_pointer];
-        // "two"
+            // access members with a JSON pointer (RFC 6901)
+            j_original["/baz/1"_json_pointer];
+            // "two"
 
-        // a JSON patch (RFC 6902)
-        json j_patch = R"([
+            // a JSON patch (RFC 6902)
+            json j_patch = R"([
           { "op": "replace", "path": "/baz", "value": "boo" },
           { "op": "add", "path": "/hello", "value": ["world"] },
           { "op": "remove", "path": "/foo"}
         ])"_json;
 
-        // apply the patch
-        json j_result = j_original.patch(j_patch);
-        // {
-        //    "baz": "boo",
-        //    "hello": ["world"]
-        // }
+            // apply the patch
+            json j_result = j_original.patch(j_patch);
+            // {
+            //    "baz": "boo",
+            //    "hello": ["world"]
+            // }
 
-        // calculate a JSON patch from two JSON values
-        json::diff(j_result, j_original);
-        // [
-        //   { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] },
-        //   { "op":"remove","path":"/hello" },
-        //   { "op":"add","path":"/foo","value":"bar" }
-        // ]
+            // calculate a JSON patch from two JSON values
+            json::diff(j_result, j_original);
+            // [
+            //   { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] },
+            //   { "op":"remove","path":"/hello" },
+            //   { "op":"add","path":"/foo","value":"bar" }
+            // ]
+        }
+
+        // restore old std::cout
+        std::cout.rdbuf(old_cout_buffer);
     }
 }