From ca2bbdb15b761184744db4c46fdc3167d620a26f Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Fri, 24 Jun 2016 07:39:08 +0200
Subject: [PATCH 01/31] clarified MSV version

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 21ff3c59..881460f4 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-![JSON for Modern C++](https://raw.githubusercontent.com/nlohmann/json/master/doc/json.gif)
+[![JSON for Modern C++](https://raw.githubusercontent.com/nlohmann/json/master/doc/json.gif)](https://github.com/nlohmann/json/releases)
 
 [![Build Status](https://travis-ci.org/nlohmann/json.svg?branch=master)](https://travis-ci.org/nlohmann/json)
 [![Build Status](https://ci.appveyor.com/api/projects/status/1acb366xfyg3qybk?svg=true)](https://ci.appveyor.com/project/nlohmann/json)
@@ -390,7 +390,7 @@ Though it's 2016 already, the support for C++11 is still a bit sparse. Currently
 
 - GCC 4.9 - 6.0 (and possibly later)
 - Clang 3.4 - 3.9 (and possibly later)
-- Microsoft Visual C++ 2015 / 14.0 (and possibly later)
+- Microsoft Visual C++ 2015 / 14.0, MSVC 19.0 (and possibly later)
 
 I would be happy to learn about other compilers/versions.
 

From 0767290c2605cb238865260da261c7d294b83edd Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Fri, 24 Jun 2016 08:06:41 +0200
Subject: [PATCH 02/31] off-by-one error in the documentation

---
 README.md         | 2 +-
 test/src/unit.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 881460f4..d2a1ef56 100644
--- a/README.md
+++ b/README.md
@@ -323,7 +323,7 @@ json j_original = R"({
 })"_json;
 
 // access members with a JSON pointer (RFC 6901)
-j_original["/baz/2"_json_pointer];
+j_original["/baz/1"_json_pointer];
 // "two"
 
 // a JSON patch (RFC 6902)
diff --git a/test/src/unit.cpp b/test/src/unit.cpp
index 298a2bb1..fe3bc773 100644
--- a/test/src/unit.cpp
+++ b/test/src/unit.cpp
@@ -10531,7 +10531,7 @@ TEST_CASE("README", "[hide]")
         })"_json;
 
         // access members with a JSON pointer (RFC 6901)
-        j_original["/baz/2"_json_pointer];
+        j_original["/baz/1"_json_pointer];
         // "two"
 
         // a JSON patch (RFC 6902)

From 6aad67af2397000c05214e6e605118de732443de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A1rio=20Feroldi?= <thlst1101@gmail.com>
Date: Fri, 24 Jun 2016 05:47:00 -0300
Subject: [PATCH 03/31] fixed a tiny typo

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index d2a1ef56..230cfd6b 100644
--- a/README.md
+++ b/README.md
@@ -291,7 +291,7 @@ json j_umset(c_umset); // both entries for "one" are used
 // maybe ["one", "two", "one", "four"]
 ```
 
-Likewise, any associative key-value containers (`std::map`, `std::multimap`, `std::unordered_map`, `std::unordered_multimap`) whose keys are can construct an `std::string` and whose values can be used to construct JSON types (see examples above) can be used to to create a JSON object. Note that in case of multimaps only one key is used in the JSON object and the value depends on the internal order of the STL container.
+Likewise, any associative key-value containers (`std::map`, `std::multimap`, `std::unordered_map`, `std::unordered_multimap`) whose keys can construct an `std::string` and whose values can be used to construct JSON types (see examples above) can be used to to create a JSON object. Note that in case of multimaps only one key is used in the JSON object and the value depends on the internal order of the STL container.
 
 ```cpp
 std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };

From c74b9ff4f7d5d0e11f711292165f17423d8233f1 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Fri, 24 Jun 2016 17:15:54 +0200
Subject: [PATCH 04/31] another fix for the MSVC version

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 230cfd6b..0ab6adcb 100644
--- a/README.md
+++ b/README.md
@@ -390,7 +390,7 @@ Though it's 2016 already, the support for C++11 is still a bit sparse. Currently
 
 - GCC 4.9 - 6.0 (and possibly later)
 - Clang 3.4 - 3.9 (and possibly later)
-- Microsoft Visual C++ 2015 / 14.0, MSVC 19.0 (and possibly later)
+- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
 
 I would be happy to learn about other compilers/versions.
 

From 360f0f3791d4c2c36bc0710885c1c88d47103c13 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Fri, 24 Jun 2016 17:39:03 +0200
Subject: [PATCH 05/31] updated README and ChangeLog

---
 ChangeLog.md | 7 ++++++-
 README.md    | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/ChangeLog.md b/ChangeLog.md
index ae9e562f..2a8d85d3 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -3,7 +3,12 @@ All notable changes to this project will be documented in this file. This projec
 
 ## [Unreleased](https://github.com/nlohmann/json/tree/HEAD)
 
-[Full Changelog](https://github.com/nlohmann/json/compare/v1.1.0...HEAD)
+[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.0...HEAD)
+
+- fixed a tiny typo [\#271](https://github.com/nlohmann/json/pull/271) ([thelostt](https://github.com/thelostt))
+
+## [v2.0.0](https://github.com/nlohmann/json/releases/tag/v2.0.0) (2016-06-23)
+[Full Changelog](https://github.com/nlohmann/json/compare/v1.1.0...v2.0.0)
 
 - concatenate objects [\#252](https://github.com/nlohmann/json/issues/252)
 - Unit test fails when doing a CMake out-of-tree build [\#241](https://github.com/nlohmann/json/issues/241)
diff --git a/README.md b/README.md
index 0ab6adcb..c271f76c 100644
--- a/README.md
+++ b/README.md
@@ -483,6 +483,7 @@ I deeply appreciate the help of the following people.
 - [Róbert Márki](https://github.com/robertmrk) added a fix to use move iterators and improved the integration via CMake.
 - [Chris Kitching](https://github.com/ChrisKitching) cleaned up the CMake files.
 - [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.
 
 Thanks a lot for helping out!
 

From 420659f1870b0871dfaf31d106bf9fcc8bc0dfd1 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 28 Jun 2016 10:42:17 +0200
Subject: [PATCH 06/31] addressing #272

---
 src/json.hpp      | 11 ++++++-----
 src/json.hpp.re2c | 11 ++++++-----
 test/src/unit.cpp |  4 ++++
 3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index b02a1344..3c57c42f 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -2097,6 +2097,8 @@ class basic_json
     string_t dump(const int indent = -1) const
     {
         std::stringstream ss;
+        // fix locale problems
+        ss.imbue(std::locale(std::locale(), new DecimalSeparator));
 
         if (indent >= 0)
         {
@@ -5655,6 +5657,8 @@ class basic_json
 
         // reset width to 0 for subsequent calls to this stream
         o.width(0);
+        // fix locale problems
+        o.imbue(std::locale(std::locale(), new DecimalSeparator));
 
         // do the actual serialization
         j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
@@ -6128,11 +6132,8 @@ class basic_json
                     // string->double->string or string->long
                     // double->string; to be safe, we read this value from
                     // std::numeric_limits<number_float_t>::digits10
-                    std::stringstream ss;
-                    ss.imbue(std::locale(std::locale(), new DecimalSeparator));  // fix locale problems
-                    ss << std::setprecision(std::numeric_limits<double>::digits10)
-                       << m_value.number_float;
-                    o << ss.str();
+                    o << std::setprecision(std::numeric_limits<double>::digits10)
+                      << m_value.number_float;
                 }
                 return;
             }
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index aba10b49..63141e20 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -2097,6 +2097,8 @@ class basic_json
     string_t dump(const int indent = -1) const
     {
         std::stringstream ss;
+        // fix locale problems
+        ss.imbue(std::locale(std::locale(), new DecimalSeparator));
 
         if (indent >= 0)
         {
@@ -5655,6 +5657,8 @@ class basic_json
 
         // reset width to 0 for subsequent calls to this stream
         o.width(0);
+        // fix locale problems
+        o.imbue(std::locale(std::locale(), new DecimalSeparator));
 
         // do the actual serialization
         j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
@@ -6128,11 +6132,8 @@ class basic_json
                     // string->double->string or string->long
                     // double->string; to be safe, we read this value from
                     // std::numeric_limits<number_float_t>::digits10
-                    std::stringstream ss;
-                    ss.imbue(std::locale(std::locale(), new DecimalSeparator));  // fix locale problems
-                    ss << std::setprecision(std::numeric_limits<double>::digits10)
-                       << m_value.number_float;
-                    o << ss.str();
+                    o << std::setprecision(std::numeric_limits<double>::digits10)
+                      << m_value.number_float;
                 }
                 return;
             }
diff --git a/test/src/unit.cpp b/test/src/unit.cpp
index fe3bc773..af16f00d 100644
--- a/test/src/unit.cpp
+++ b/test/src/unit.cpp
@@ -14079,6 +14079,10 @@ TEST_CASE("regression tests")
         CHECK(j1a.dump() == "23.42");
         CHECK(j1b.dump() == "23.42");
 
+        std::stringstream ss;
+        ss << j1a;
+        CHECK(ss.str() == "23.42");
+
         CHECK(j2a.dump() == "23.42");
         //issue #230
         //CHECK(j2b.dump() == "23.42");

From 7214243d89b166d8b52c18a997720a5fe4be2fe6 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 28 Jun 2016 19:18:23 +0200
Subject: [PATCH 07/31] reset locale (for #272)

---
 src/json.hpp      | 5 ++++-
 src/json.hpp.re2c | 5 ++++-
 test/src/unit.cpp | 8 +++++++-
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 3c57c42f..7adcbb43 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -5658,10 +5658,13 @@ class basic_json
         // reset width to 0 for subsequent calls to this stream
         o.width(0);
         // fix locale problems
-        o.imbue(std::locale(std::locale(), new DecimalSeparator));
+        auto old_locale = o.imbue(std::locale(std::locale(), new DecimalSeparator));
 
         // do the actual serialization
         j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
+
+        // reset locale
+        o.imbue(old_locale);
         return o;
     }
 
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 63141e20..4b86afd6 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -5658,10 +5658,13 @@ class basic_json
         // reset width to 0 for subsequent calls to this stream
         o.width(0);
         // fix locale problems
-        o.imbue(std::locale(std::locale(), new DecimalSeparator));
+        auto old_locale = o.imbue(std::locale(std::locale(), new DecimalSeparator));
 
         // do the actual serialization
         j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
+
+        // reset locale
+        o.imbue(old_locale);
         return o;
     }
 
diff --git a/test/src/unit.cpp b/test/src/unit.cpp
index af16f00d..1f5c6d9f 100644
--- a/test/src/unit.cpp
+++ b/test/src/unit.cpp
@@ -14079,9 +14079,15 @@ TEST_CASE("regression tests")
         CHECK(j1a.dump() == "23.42");
         CHECK(j1b.dump() == "23.42");
 
+        // check if locale is properly reset
         std::stringstream ss;
+        ss.imbue(std::locale(std::locale(), new CommaDecimalSeparator));
+        ss << 47.11;
+        CHECK(ss.str() == "47,11");
         ss << j1a;
-        CHECK(ss.str() == "23.42");
+        CHECK(ss.str() == "47,1123.42");
+        ss << 47.11;
+        CHECK(ss.str() == "47,1123.4247,11");
 
         CHECK(j2a.dump() == "23.42");
         //issue #230

From a73bda814723f71ee5a55e8af8903667623977f8 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 28 Jun 2016 21:24:18 +0200
Subject: [PATCH 08/31] fixed performance regression #272

---
 README.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index c271f76c..4ad40373 100644
--- a/README.md
+++ b/README.md
@@ -484,6 +484,7 @@ I deeply appreciate the help of the following people.
 - [Chris Kitching](https://github.com/ChrisKitching) cleaned up the CMake files.
 - [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.
 
 Thanks a lot for helping out!
 
@@ -503,7 +504,7 @@ $ make
 $ ./json_unit "*"
 
 ===============================================================================
-All tests passed (5568715 assertions in 32 test cases)
+All tests passed (5568718 assertions in 32 test cases)
 ```
 
 For more information, have a look at the file [.travis.yml](https://github.com/nlohmann/json/blob/master/.travis.yml).

From 026fe8041db32d226a902bc1da10c7014c94ff5c Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 28 Jun 2016 21:33:34 +0200
Subject: [PATCH 09/31] adjusted Changelog

---
 ChangeLog.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ChangeLog.md b/ChangeLog.md
index 2a8d85d3..0565f288 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file. This projec
 
 [Full Changelog](https://github.com/nlohmann/json/compare/v2.0.0...HEAD)
 
+- dump\(\) performance degradation in v2 [\#272](https://github.com/nlohmann/json/issues/272)
+
 - fixed a tiny typo [\#271](https://github.com/nlohmann/json/pull/271) ([thelostt](https://github.com/thelostt))
 
 ## [v2.0.0](https://github.com/nlohmann/json/releases/tag/v2.0.0) (2016-06-23)

From d2475f9010e880b04c19987e8211b05b6bb1e022 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 28 Jun 2016 21:44:03 +0200
Subject: [PATCH 10/31] bumped version number

---
 src/json.hpp      | 2 +-
 src/json.hpp.re2c | 2 +-
 test/src/unit.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 7adcbb43..35bdd293 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++
-|  |  |__   |  |  | | | |  version 2.0.0
+|  |  |__   |  |  | | | |  version 2.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 4b86afd6..016ff0c5 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++
-|  |  |__   |  |  | | | |  version 2.0.0
+|  |  |__   |  |  | | | |  version 2.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit.cpp b/test/src/unit.cpp
index 1f5c6d9f..3b8909ac 100644
--- a/test/src/unit.cpp
+++ b/test/src/unit.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 2.0.0
+|  |  |__   |  |  | | | |  version 2.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.

From 7ffa07e3a3b21a2fec08da9c7d4fda8b7d043ff9 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 28 Jun 2016 21:46:53 +0200
Subject: [PATCH 11/31] update of ChangeLog

---
 ChangeLog.md | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/ChangeLog.md b/ChangeLog.md
index 0565f288..34d28e4d 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,9 +1,8 @@
 # Change Log
 All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
 
-## [Unreleased](https://github.com/nlohmann/json/tree/HEAD)
-
-[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.0...HEAD)
+## [v2.0.1](https://github.com/nlohmann/json/releases/tag/v2.0.1) (2016-06-28)
+[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.0...v2.0.1)
 
 - dump\(\) performance degradation in v2 [\#272](https://github.com/nlohmann/json/issues/272)
 

From dc479b3f9de06dea12105c6ea21ee263dcfd8d6a Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 28 Jun 2016 22:09:22 +0200
Subject: [PATCH 12/31] check for unsupported compilers

---
 src/json.hpp      | 14 ++++++++++++++
 src/json.hpp.re2c | 14 ++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/src/json.hpp b/src/json.hpp
index 35bdd293..1673fb17 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -53,6 +53,20 @@ SOFTWARE.
 #include <utility>
 #include <vector>
 
+// exclude unsupported compilers
+#if defined(__clang__)
+    #define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
+    #if CLANG_VERSION < 34000
+        #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
+    #endif
+#endif
+#if defined(__GNUC__)
+    #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+    #if GCC_VERSION < 48000
+        #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
+    #endif
+#endif
+
 // disable float-equal warnings on GCC/clang
 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
     #pragma GCC diagnostic push
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 016ff0c5..2672c1d0 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -53,6 +53,20 @@ SOFTWARE.
 #include <utility>
 #include <vector>
 
+// exclude unsupported compilers
+#if defined(__clang__)
+    #define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
+    #if CLANG_VERSION < 34000
+        #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
+    #endif
+#endif
+#if defined(__GNUC__)
+    #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+    #if GCC_VERSION < 48000
+        #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
+    #endif
+#endif
+
 // disable float-equal warnings on GCC/clang
 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
     #pragma GCC diagnostic push

From fc7f4b8fba1ed63f700d690ce4904ec851fc20ab Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 28 Jun 2016 22:49:05 +0200
Subject: [PATCH 13/31] replace some raw loops with algorithms

---
 src/json.hpp      | 62 +++++++++++++++++++++--------------------------
 src/json.hpp.re2c | 62 +++++++++++++++++++++--------------------------
 2 files changed, 54 insertions(+), 70 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 35bdd293..fcb5e733 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -46,6 +46,7 @@ SOFTWARE.
 #include <limits>
 #include <map>
 #include <memory>
+#include <numeric>
 #include <sstream>
 #include <stdexcept>
 #include <string>
@@ -1554,22 +1555,13 @@ class basic_json
                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)
@@ -1595,10 +1587,10 @@ class basic_json
 
             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
         {
@@ -3235,11 +3227,13 @@ class basic_json
         // 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);
@@ -5832,9 +5826,8 @@ class basic_json
     */
     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)
             {
@@ -5847,8 +5840,7 @@ class basic_json
                 case '\t':
                 {
                     // from c (1 byte) to \x (2 bytes)
-                    result += 1;
-                    break;
+                    return res + 1;
                 }
 
                 default:
@@ -5856,14 +5848,15 @@ class basic_json
                     if (c >= 0x00 and c <= 0x1f)
                     {
                         // from c (1 byte) to \uxxxx (6 bytes)
-                        result += 5;
+                        return res + 5;
+                    }
+                    else
+                    {
+                        return res;
                     }
-                    break;
                 }
             }
-        }
-
-        return result;
+        });
     }
 
     /*!
@@ -8778,14 +8771,13 @@ basic_json_parser_63:
         */
         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 016ff0c5..dea0f51c 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -46,6 +46,7 @@ SOFTWARE.
 #include <limits>
 #include <map>
 #include <memory>
+#include <numeric>
 #include <sstream>
 #include <stdexcept>
 #include <string>
@@ -1554,22 +1555,13 @@ class basic_json
                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)
@@ -1595,10 +1587,10 @@ class basic_json
 
             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
         {
@@ -3235,11 +3227,13 @@ class basic_json
         // 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);
@@ -5832,9 +5826,8 @@ class basic_json
     */
     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)
             {
@@ -5847,8 +5840,7 @@ class basic_json
                 case '\t':
                 {
                     // from c (1 byte) to \x (2 bytes)
-                    result += 1;
-                    break;
+                    return res + 1;
                 }
 
                 default:
@@ -5856,14 +5848,15 @@ class basic_json
                     if (c >= 0x00 and c <= 0x1f)
                     {
                         // from c (1 byte) to \uxxxx (6 bytes)
-                        result += 5;
+                        return res + 5;
+                    }
+                    else
+                    {
+                        return res;
                     }
-                    break;
                 }
             }
-        }
-
-        return result;
+        });
     }
 
     /*!
@@ -8088,14 +8081,13 @@ class basic_json
         */
         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()

From d456dec320b198c1376cd10cb1697038f341de08 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Wed, 29 Jun 2016 09:16:18 +0200
Subject: [PATCH 14/31] overlapping defines

---
 src/json.hpp      | 3 +--
 src/json.hpp.re2c | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 1673fb17..eaa3a44e 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -59,8 +59,7 @@ SOFTWARE.
     #if CLANG_VERSION < 34000
         #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
     #endif
-#endif
-#if defined(__GNUC__)
+#elif defined(__GNUC__)
     #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
     #if GCC_VERSION < 48000
         #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 2672c1d0..9c94a2ba 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -59,8 +59,7 @@ SOFTWARE.
     #if CLANG_VERSION < 34000
         #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
     #endif
-#endif
-#if defined(__GNUC__)
+#elif defined(__GNUC__)
     #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
     #if GCC_VERSION < 48000
         #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"

From 7cb8ee42d52bd773bdd55bd873c3f48565060ed0 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Wed, 29 Jun 2016 09:22:28 +0200
Subject: [PATCH 15/31] wrong GCC version

---
 src/json.hpp      | 2 +-
 src/json.hpp.re2c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index eaa3a44e..92b913a8 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -61,7 +61,7 @@ SOFTWARE.
     #endif
 #elif defined(__GNUC__)
     #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-    #if GCC_VERSION < 48000
+    #if GCC_VERSION < 49000
         #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
     #endif
 #endif
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 9c94a2ba..cc4df5de 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -61,7 +61,7 @@ SOFTWARE.
     #endif
 #elif defined(__GNUC__)
     #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-    #if GCC_VERSION < 48000
+    #if GCC_VERSION < 49000
         #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
     #endif
 #endif

From 924f78119b6160cd26daec2b5eeb4837483d4e43 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Wed, 29 Jun 2016 09:34:14 +0200
Subject: [PATCH 16/31] math...

---
 src/json.hpp      | 4 ++--
 src/json.hpp.re2c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 92b913a8..d73abe0c 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -56,12 +56,12 @@ SOFTWARE.
 // exclude unsupported compilers
 #if defined(__clang__)
     #define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
-    #if CLANG_VERSION < 34000
+    #if CLANG_VERSION < 30400
         #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
     #endif
 #elif defined(__GNUC__)
     #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-    #if GCC_VERSION < 49000
+    #if GCC_VERSION < 40900
         #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
     #endif
 #endif
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index cc4df5de..2d573258 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -56,12 +56,12 @@ SOFTWARE.
 // exclude unsupported compilers
 #if defined(__clang__)
     #define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
-    #if CLANG_VERSION < 34000
+    #if CLANG_VERSION < 30400
         #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
     #endif
 #elif defined(__GNUC__)
     #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-    #if GCC_VERSION < 49000
+    #if GCC_VERSION < 40900
         #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
     #endif
 #endif

From a0609b2da311ab68978e136eac770bc7aed4bd95 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Wed, 29 Jun 2016 09:53:48 +0200
Subject: [PATCH 17/31] fixed coverage bug

---
 src/json.hpp      | 3 +--
 src/json.hpp.re2c | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index fcb5e733..78c5c54e 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8773,8 +8773,7 @@ basic_json_parser_63:
         {
             return std::accumulate(reference_tokens.begin(),
                                    reference_tokens.end(), std::string{},
-                                   [](const std::string & a,
-                                      const std::string & b)
+                                   [](const std::string & a, const std::string & b)
             {
                 return a + "/" + escape(b);
             });
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index dea0f51c..c484c5e8 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -8083,8 +8083,7 @@ class basic_json
         {
             return std::accumulate(reference_tokens.begin(),
                                    reference_tokens.end(), std::string{},
-                                   [](const std::string & a,
-                                      const std::string & b)
+                                   [](const std::string & a, const std::string & b)
             {
                 return a + "/" + escape(b);
             });

From 52cbda80484d112d2af352ddd608ea3cb76d73db Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Wed, 29 Jun 2016 12:47:29 +0200
Subject: [PATCH 18/31] using std::advance where possible

---
 src/json.hpp      | 12 ++++++------
 src/json.hpp.re2c | 12 ++++++------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 78c5c54e..57618dd0 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -6606,13 +6606,13 @@ class basic_json
             {
                 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;
                 }
 
@@ -6643,13 +6643,13 @@ class basic_json
             {
                 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;
                 }
 
@@ -6761,7 +6761,7 @@ class basic_json
 
                 case basic_json::value_t::array:
                 {
-                    m_it.array_iterator += i;
+                    std::advance(m_it.array_iterator, i);
                     break;
                 }
 
@@ -6835,7 +6835,7 @@ class basic_json
 
                 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:
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index c484c5e8..cf0d4df8 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -6606,13 +6606,13 @@ class basic_json
             {
                 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;
                 }
 
@@ -6643,13 +6643,13 @@ class basic_json
             {
                 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;
                 }
 
@@ -6761,7 +6761,7 @@ class basic_json
 
                 case basic_json::value_t::array:
                 {
-                    m_it.array_iterator += i;
+                    std::advance(m_it.array_iterator, i);
                     break;
                 }
 
@@ -6835,7 +6835,7 @@ class basic_json
 
                 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:

From 5c129c898158c93f751985c305296d781891d814 Mon Sep 17 00:00:00 2001
From: dtoma <damientoma.pro@gmail.com>
Date: Wed, 29 Jun 2016 19:28:56 +0800
Subject: [PATCH 19/31] Update hexify to use array lookup instead of ternary
 (#270)

---
 src/json.hpp.re2c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 016ff0c5..adc2e188 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -5959,9 +5959,11 @@ class basic_json
                         // (0..f)
                         const auto hexify = [](const int v) -> char
                         {
-                            return (v < 10)
-                            ? ('0' + static_cast<char>(v))
-                            : ('a' + static_cast<char>((v - 10) & 0x1f));
+						    static const char hex[16] = { '0', '1', '2', '3',
+                                                          '4', '5', '6', '7',
+                                                          '8', '9', 'a', 'b',
+                                                          'c', 'd', 'e', 'f' };
+						    return hex[v];
                         };
 
                         // print character c as \uxxxx

From a5262c18e23bbbd45d677226e20ea3952f52bb30 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Thu, 30 Jun 2016 12:43:06 +0200
Subject: [PATCH 20/31] replaced a copy by a move to increase performance by
 16-25%

---
 src/json.hpp      | 2 +-
 src/json.hpp.re2c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 35bdd293..d9c75c4a 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8480,7 +8480,7 @@ basic_json_parser_63:
 
             // return parser result and replace it with null in case the
             // top-level value was discarded by the callback function
-            return result.is_discarded() ? basic_json() : result;
+            return result.is_discarded() ? basic_json() : std::move(result);
         }
 
       private:
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 016ff0c5..ba045342 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -7790,7 +7790,7 @@ class basic_json
 
             // return parser result and replace it with null in case the
             // top-level value was discarded by the callback function
-            return result.is_discarded() ? basic_json() : result;
+            return result.is_discarded() ? basic_json() : std::move(result);
         }
 
       private:

From 26cab42c382b2a0ff7a8f3d45b3219721ad63906 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Fri, 1 Jul 2016 16:52:05 +0200
Subject: [PATCH 21/31] some minor improvements

---
 doc/examples/count.cpp  |  1 -
 doc/examples/count.link |  2 +-
 src/json.hpp            | 91 +++++++++++++++++++++++++++++++---------
 src/json.hpp.re2c       | 93 +++++++++++++++++++++++++++++++----------
 4 files changed, 144 insertions(+), 43 deletions(-)

diff --git a/doc/examples/count.cpp b/doc/examples/count.cpp
index a805eeb6..b97f71da 100644
--- a/doc/examples/count.cpp
+++ b/doc/examples/count.cpp
@@ -12,7 +12,6 @@ int main()
     auto count_three = j_object.count("three");
 
     // print values
-    std::cout << std::boolalpha;
     std::cout << "number of elements with key \"two\": " << count_two << '\n';
     std::cout << "number of elements with key \"three\": " << count_three << '\n';
 }
diff --git a/doc/examples/count.link b/doc/examples/count.link
index 62833ff4..0893d922 100644
--- a/doc/examples/count.link
+++ b/doc/examples/count.link
@@ -1 +1 @@
-<a target="_blank" href="http://melpon.org/wandbox/permlink/XoXqF9LlWu8jlNgE"><b>online</b></a>
\ No newline at end of file
+<a target="_blank" href="http://melpon.org/wandbox/permlink/yv5TMrq9qREivvHf"><b>online</b></a>
\ No newline at end of file
diff --git a/src/json.hpp b/src/json.hpp
index 35bdd293..cef0f26d 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -76,7 +76,13 @@ namespace
 {
 /*!
 @brief Helper to determine whether there's a key_type for T.
+
+Thus helper is used to tell associative containers apart from other containers
+such as sequence containers. For instance, `std::map` passes the test as it
+contains a `mapped_type`, whereas `std::vector` fails the test.
+
 @sa http://stackoverflow.com/a/7728728/266378
+@since version 1.0.0
 */
 template<typename T>
 struct has_mapped_type
@@ -90,11 +96,18 @@ struct has_mapped_type
 
 /*!
 @brief helper class to create locales with decimal point
+
+This struct is used a default locale during the JSON serialization. JSON
+requires the decimal point to be `.`, so this function overloads the
+`do_decimal_point()` function to return `.`. This function is called by
+float-to-string conversions to retrieve the decimal separator between integer
+and fractional parts.
+
 @sa https://github.com/nlohmann/json/issues/51#issuecomment-86869315
+@since version 2.0.0
 */
-class DecimalSeparator : public std::numpunct<char>
+struct DecimalSeparator : std::numpunct<char>
 {
-  protected:
     char do_decimal_point() const
     {
         return '.';
@@ -188,13 +201,8 @@ class basic_json
 {
   private:
     /// workaround type for MSVC
-    using basic_json_t = basic_json<ObjectType,
-          ArrayType,
-          StringType,
-          BooleanType,
-          NumberIntegerType,
-          NumberUnsignedType,
-          NumberFloatType,
+    using basic_json_t = basic_json<ObjectType, ArrayType, StringType,
+          BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
           AllocatorType>;
 
   public:
@@ -207,6 +215,8 @@ class basic_json
     /////////////////////
 
     /// @name container types
+    /// The canonic container types to use @ref basic_json like any other STL
+    /// container.
     /// @{
 
     /// the type of elements in a basic_json container
@@ -256,6 +266,8 @@ class basic_json
     ///////////////////////////
 
     /// @name JSON value data types
+    /// The data types to store a JSON value. These types are derived from
+    /// the template arguments passed to class @ref basic_json.
     /// @{
 
     /*!
@@ -923,6 +935,8 @@ class basic_json
     //////////////////
 
     /// @name constructors and destructors
+    /// Constructors of class @ref basic_json, copy/move constructor, copy
+    /// assignment, static functions creating objects, and the destructor.
     /// @{
 
     /*!
@@ -2069,19 +2083,20 @@ class basic_json
     ///////////////////////
 
     /// @name object inspection
+    /// Functions to inspect the type of a JSON value.
     /// @{
 
     /*!
     @brief serialization
 
     Serialization function for JSON values. The function tries to mimic
-    Python's @p json.dumps() function, and currently supports its @p indent
+    Python's `json.dumps()` function, and currently supports its @a indent
     parameter.
 
-    @param[in] indent if indent is nonnegative, then array elements and object
+    @param[in] indent If indent is nonnegative, then array elements and object
     members will be pretty-printed with that indent level. An indent level of
-    0 will only insert newlines. -1 (the default) selects the most compact
-    representation
+    `0` will only insert newlines. `-1` (the default) selects the most compact
+    representation.
 
     @return string containing the serialization of the JSON value
 
@@ -2767,6 +2782,7 @@ class basic_json
   public:
 
     /// @name value access
+    /// Direct access to the stored value of a JSON value.
     /// @{
 
     /*!
@@ -2817,7 +2833,8 @@ class basic_json
     Explicit pointer access to the internally stored JSON value. No copies are
     made.
 
-    @warning The pointer becomes invalid if the underlying JSON object changes.
+    @warning The pointer becomes invalid if the underlying JSON object
+    changes.
 
     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
@@ -2872,7 +2889,8 @@ class basic_json
 
     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
-    @ref number_unsigned_t, or @ref number_float_t.
+    @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
+    assertion.
 
     @return pointer to the internally stored JSON value if the requested
     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
@@ -2892,6 +2910,21 @@ class basic_json
                  , int>::type = 0>
     PointerType get_ptr() noexcept
     {
+        // get the type of the PointerType (remove pointer and const)
+        using pointee_t = typename std::remove_const<typename
+                          std::remove_pointer<typename
+                          std::remove_const<PointerType>::type>::type>::type;
+        // make sure the type matches the allowed types
+        static_assert(
+            std::is_same<object_t, pointee_t>::value
+            or std::is_same<array_t, pointee_t>::value
+            or std::is_same<string_t, pointee_t>::value
+            or std::is_same<boolean_t, pointee_t>::value
+            or std::is_same<number_integer_t, pointee_t>::value
+            or std::is_same<number_unsigned_t, pointee_t>::value
+            or std::is_same<number_float_t, pointee_t>::value
+            , "incompatible pointer type");
+
         // delegate the call to get_impl_ptr<>()
         return get_impl_ptr(static_cast<PointerType>(nullptr));
     }
@@ -2907,6 +2940,21 @@ class basic_json
                  , int>::type = 0>
     constexpr const PointerType get_ptr() const noexcept
     {
+        // get the type of the PointerType (remove pointer and const)
+        using pointee_t = typename std::remove_const<typename
+                          std::remove_pointer<typename
+                          std::remove_const<PointerType>::type>::type>::type;
+        // make sure the type matches the allowed types
+        static_assert(
+            std::is_same<object_t, pointee_t>::value
+            or std::is_same<array_t, pointee_t>::value
+            or std::is_same<string_t, pointee_t>::value
+            or std::is_same<boolean_t, pointee_t>::value
+            or std::is_same<number_integer_t, pointee_t>::value
+            or std::is_same<number_unsigned_t, pointee_t>::value
+            or std::is_same<number_float_t, pointee_t>::value
+            , "incompatible pointer type");
+
         // delegate the call to get_impl_ptr<>() const
         return get_impl_ptr(static_cast<const PointerType>(nullptr));
     }
@@ -2922,7 +2970,7 @@ class basic_json
 
     @tparam ReferenceType reference type; must be a reference to @ref array_t,
     @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
-    @ref number_float_t.
+    @ref number_float_t. Enforced by static assertion.
 
     @return reference to the internally stored JSON value if the requested
     reference type @a ReferenceType fits to the JSON value; throws
@@ -3012,6 +3060,7 @@ class basic_json
     ////////////////////
 
     /// @name element access
+    /// Access to the JSON value.
     /// @{
 
     /*!
@@ -8127,7 +8176,7 @@ basic_json_parser_63:
         }
 
         /// return string representation of last read token
-        string_t get_token() const
+        string_t get_token_string() const
         {
             assert(m_start != nullptr);
             return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
@@ -8395,7 +8444,7 @@ basic_json_parser_63:
                 if (type != value_t::number_float)
                 {
                     // multiply last value by ten and add the new digit
-                    auto temp = value * 10 + *curptr - 0x30;
+                    auto temp = value * 10 + *curptr - '0';
 
                     // test for overflow
                     if (temp < value || temp > max)
@@ -8688,7 +8737,8 @@ basic_json_parser_63:
             if (t != last_token)
             {
                 std::string error_msg = "parse error - unexpected ";
-                error_msg += (last_token == lexer::token_type::parse_error ? ("'" +  m_lexer.get_token() + "'") :
+                error_msg += (last_token == lexer::token_type::parse_error ? ("'" +  m_lexer.get_token_string() +
+                              "'") :
                               lexer::token_type_name(last_token));
                 error_msg += "; expected " + lexer::token_type_name(t);
                 throw std::invalid_argument(error_msg);
@@ -8700,7 +8750,8 @@ basic_json_parser_63:
             if (t == last_token)
             {
                 std::string error_msg = "parse error - unexpected ";
-                error_msg += (last_token == lexer::token_type::parse_error ? ("'" +  m_lexer.get_token() + "'") :
+                error_msg += (last_token == lexer::token_type::parse_error ? ("'" +  m_lexer.get_token_string() +
+                              "'") :
                               lexer::token_type_name(last_token));
                 throw std::invalid_argument(error_msg);
             }
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 016ff0c5..8ac900c2 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -76,7 +76,13 @@ namespace
 {
 /*!
 @brief Helper to determine whether there's a key_type for T.
+
+Thus helper is used to tell associative containers apart from other containers
+such as sequence containers. For instance, `std::map` passes the test as it
+contains a `mapped_type`, whereas `std::vector` fails the test.
+
 @sa http://stackoverflow.com/a/7728728/266378
+@since version 1.0.0
 */
 template<typename T>
 struct has_mapped_type
@@ -90,11 +96,18 @@ struct has_mapped_type
 
 /*!
 @brief helper class to create locales with decimal point
+
+This struct is used a default locale during the JSON serialization. JSON
+requires the decimal point to be `.`, so this function overloads the
+`do_decimal_point()` function to return `.`. This function is called by
+float-to-string conversions to retrieve the decimal separator between integer
+and fractional parts.
+
 @sa https://github.com/nlohmann/json/issues/51#issuecomment-86869315
+@since version 2.0.0
 */
-class DecimalSeparator : public std::numpunct<char>
+struct DecimalSeparator : std::numpunct<char>
 {
-  protected:
     char do_decimal_point() const
     {
         return '.';
@@ -188,13 +201,8 @@ class basic_json
 {
   private:
     /// workaround type for MSVC
-    using basic_json_t = basic_json<ObjectType,
-          ArrayType,
-          StringType,
-          BooleanType,
-          NumberIntegerType,
-          NumberUnsignedType,
-          NumberFloatType,
+    using basic_json_t = basic_json<ObjectType, ArrayType, StringType,
+          BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
           AllocatorType>;
 
   public:
@@ -207,6 +215,8 @@ class basic_json
     /////////////////////
 
     /// @name container types
+    /// The canonic container types to use @ref basic_json like any other STL
+    /// container.
     /// @{
 
     /// the type of elements in a basic_json container
@@ -256,6 +266,8 @@ class basic_json
     ///////////////////////////
 
     /// @name JSON value data types
+    /// The data types to store a JSON value. These types are derived from
+    /// the template arguments passed to class @ref basic_json.
     /// @{
 
     /*!
@@ -923,6 +935,8 @@ class basic_json
     //////////////////
 
     /// @name constructors and destructors
+    /// Constructors of class @ref basic_json, copy/move constructor, copy
+    /// assignment, static functions creating objects, and the destructor.
     /// @{
 
     /*!
@@ -2069,19 +2083,20 @@ class basic_json
     ///////////////////////
 
     /// @name object inspection
+    /// Functions to inspect the type of a JSON value.
     /// @{
 
     /*!
     @brief serialization
 
     Serialization function for JSON values. The function tries to mimic
-    Python's @p json.dumps() function, and currently supports its @p indent
+    Python's `json.dumps()` function, and currently supports its @a indent
     parameter.
 
-    @param[in] indent if indent is nonnegative, then array elements and object
+    @param[in] indent If indent is nonnegative, then array elements and object
     members will be pretty-printed with that indent level. An indent level of
-    0 will only insert newlines. -1 (the default) selects the most compact
-    representation
+    `0` will only insert newlines. `-1` (the default) selects the most compact
+    representation.
 
     @return string containing the serialization of the JSON value
 
@@ -2767,6 +2782,7 @@ class basic_json
   public:
 
     /// @name value access
+    /// Direct access to the stored value of a JSON value.
     /// @{
 
     /*!
@@ -2817,7 +2833,8 @@ class basic_json
     Explicit pointer access to the internally stored JSON value. No copies are
     made.
 
-    @warning The pointer becomes invalid if the underlying JSON object changes.
+    @warning The pointer becomes invalid if the underlying JSON object
+    changes.
 
     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
@@ -2872,7 +2889,8 @@ class basic_json
 
     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
-    @ref number_unsigned_t, or @ref number_float_t.
+    @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
+    assertion.
 
     @return pointer to the internally stored JSON value if the requested
     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
@@ -2892,6 +2910,21 @@ class basic_json
                  , int>::type = 0>
     PointerType get_ptr() noexcept
     {
+        // get the type of the PointerType (remove pointer and const)
+        using pointee_t = typename std::remove_const<typename
+                          std::remove_pointer<typename
+                          std::remove_const<PointerType>::type>::type>::type;
+        // make sure the type matches the allowed types
+        static_assert(
+            std::is_same<object_t, pointee_t>::value
+            or std::is_same<array_t, pointee_t>::value
+            or std::is_same<string_t, pointee_t>::value
+            or std::is_same<boolean_t, pointee_t>::value
+            or std::is_same<number_integer_t, pointee_t>::value
+            or std::is_same<number_unsigned_t, pointee_t>::value
+            or std::is_same<number_float_t, pointee_t>::value
+            , "incompatible pointer type");
+
         // delegate the call to get_impl_ptr<>()
         return get_impl_ptr(static_cast<PointerType>(nullptr));
     }
@@ -2907,6 +2940,21 @@ class basic_json
                  , int>::type = 0>
     constexpr const PointerType get_ptr() const noexcept
     {
+        // get the type of the PointerType (remove pointer and const)
+        using pointee_t = typename std::remove_const<typename
+                          std::remove_pointer<typename
+                          std::remove_const<PointerType>::type>::type>::type;
+        // make sure the type matches the allowed types
+        static_assert(
+            std::is_same<object_t, pointee_t>::value
+            or std::is_same<array_t, pointee_t>::value
+            or std::is_same<string_t, pointee_t>::value
+            or std::is_same<boolean_t, pointee_t>::value
+            or std::is_same<number_integer_t, pointee_t>::value
+            or std::is_same<number_unsigned_t, pointee_t>::value
+            or std::is_same<number_float_t, pointee_t>::value
+            , "incompatible pointer type");
+
         // delegate the call to get_impl_ptr<>() const
         return get_impl_ptr(static_cast<const PointerType>(nullptr));
     }
@@ -2922,7 +2970,7 @@ class basic_json
 
     @tparam ReferenceType reference type; must be a reference to @ref array_t,
     @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
-    @ref number_float_t.
+    @ref number_float_t. Enforced by static assertion.
 
     @return reference to the internally stored JSON value if the requested
     reference type @a ReferenceType fits to the JSON value; throws
@@ -3012,6 +3060,7 @@ class basic_json
     ////////////////////
 
     /// @name element access
+    /// Access to the JSON value.
     /// @{
 
     /*!
@@ -7407,7 +7456,7 @@ class basic_json
 
                 // anything else is an error
                 .              { return token_type::parse_error; }
-             */
+            */
         }
 
         /// append data from the stream to the internal buffer
@@ -7437,7 +7486,7 @@ class basic_json
         }
 
         /// return string representation of last read token
-        string_t get_token() const
+        string_t get_token_string() const
         {
             assert(m_start != nullptr);
             return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
@@ -7705,7 +7754,7 @@ class basic_json
                 if (type != value_t::number_float)
                 {
                     // multiply last value by ten and add the new digit
-                    auto temp = value * 10 + *curptr - 0x30;
+                    auto temp = value * 10 + *curptr - '0';
 
                     // test for overflow
                     if (temp < value || temp > max)
@@ -7998,7 +8047,8 @@ class basic_json
             if (t != last_token)
             {
                 std::string error_msg = "parse error - unexpected ";
-                error_msg += (last_token == lexer::token_type::parse_error ? ("'" +  m_lexer.get_token() + "'") :
+                error_msg += (last_token == lexer::token_type::parse_error ? ("'" +  m_lexer.get_token_string() +
+                              "'") :
                               lexer::token_type_name(last_token));
                 error_msg += "; expected " + lexer::token_type_name(t);
                 throw std::invalid_argument(error_msg);
@@ -8010,7 +8060,8 @@ class basic_json
             if (t == last_token)
             {
                 std::string error_msg = "parse error - unexpected ";
-                error_msg += (last_token == lexer::token_type::parse_error ? ("'" +  m_lexer.get_token() + "'") :
+                error_msg += (last_token == lexer::token_type::parse_error ? ("'" +  m_lexer.get_token_string() +
+                              "'") :
                               lexer::token_type_name(last_token));
                 throw std::invalid_argument(error_msg);
             }

From 6e1347e68c9d03f3b2563ed972e77c03d688a151 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Fri, 1 Jul 2016 16:58:50 +0200
Subject: [PATCH 22/31] fixes #270

---
 README.md         |  1 +
 src/json.hpp      |  9 ++++-----
 src/json.hpp.re2c | 11 ++++-------
 3 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/README.md b/README.md
index 4ad40373..f6b84083 100644
--- a/README.md
+++ b/README.md
@@ -485,6 +485,7 @@ I deeply appreciate the help of the following people.
 - [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 35bdd293..a6775e53 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -5957,16 +5957,15 @@ class basic_json
                     {
                         // 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;
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index adc2e188..1967f6a8 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -5957,18 +5957,15 @@ class basic_json
                     {
                         // convert a number 0..15 to its hex representation
                         // (0..f)
-                        const auto hexify = [](const int v) -> char
+                        static const char hexify[16] =
                         {
-						    static const char hex[16] = { '0', '1', '2', '3',
-                                                          '4', '5', '6', '7',
-                                                          '8', '9', 'a', 'b',
-                                                          'c', 'd', 'e', 'f' };
-						    return hex[v];
+                            '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;

From 28644bada007985dfb3002bbd1a7f7573b144633 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Fri, 1 Jul 2016 17:25:56 +0200
Subject: [PATCH 23/31] removed std::out output from test cases

---
 test/src/unit.cpp | 409 +++++++++++++++++++++++-----------------------
 1 file changed, 209 insertions(+), 200 deletions(-)

diff --git a/test/src/unit.cpp b/test/src/unit.cpp
index 3b8909ac..a12f0529 100644
--- a/test/src/unit.cpp
+++ b/test/src/unit.cpp
@@ -10309,252 +10309,261 @@ TEST_CASE("parser class")
 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);
     }
 }
 

From bd7cd330cddb78fd873e10f2d46bb16a47bfe947 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Fri, 1 Jul 2016 17:26:09 +0200
Subject: [PATCH 24/31] fixed type_name() signature

---
 src/json.hpp      | 2 +-
 src/json.hpp.re2c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index a6775e53..3cf3a139 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -5801,7 +5801,7 @@ class basic_json
     ///////////////////////////
 
     /// return the type as string
-    string_t type_name() const noexcept
+    std::string type_name() const
     {
         switch (m_type)
         {
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 1967f6a8..15ab97e6 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -5801,7 +5801,7 @@ class basic_json
     ///////////////////////////
 
     /// return the type as string
-    string_t type_name() const noexcept
+    std::string type_name() const
     {
         switch (m_type)
         {

From 98d48ef0c20f2c86f3344e98939f7d33a3e8ec5f Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Mon, 4 Jul 2016 00:04:22 +0200
Subject: [PATCH 25/31] fixed indentation

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index f6b84083..24f6d7ab 100644
--- a/README.md
+++ b/README.md
@@ -344,8 +344,8 @@ json j_result = j_original.patch(j_patch);
 json::diff(j_result, j_original);
 // [
 //   { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] },
-//   { "op":"remove","path":"/hello" },
-//   { "op":"add","path":"/foo","value":"bar" }
+//   { "op": "remove","path": "/hello" },
+//   { "op": "add", "path": "/foo", "value": "bar" }
 // ]
 ```
 

From 01f9ee5fd7f9d3a52baa8984ea5b2bcbf6428b0a Mon Sep 17 00:00:00 2001
From: Muri Nicanor <murinicanor@users.noreply.github.com>
Date: Sat, 9 Jul 2016 20:02:41 +0200
Subject: [PATCH 26/31] let the makefile choose the correct sed

---
 doc/Makefile | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/doc/Makefile b/doc/Makefile
index 5e5459a0..1fb17cfc 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,4 +1,5 @@
 SRCDIR = ../src
+SED:=$(shell command -v sed || gsed)
 
 all: doxygen
 
@@ -52,10 +53,10 @@ clean:
 # create Doxygen documentation
 doxygen: create_output create_links
 	doxygen
-	gsed -i 's@&lt; ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType &gt;@@g' html/*.html
-	gsed -i 's@&lt;&#160;ObjectType,&#160;ArrayType,&#160;StringType,&#160;BooleanType,&#160;NumberIntegerType,&#160;NumberFloatType,&#160;AllocatorType&#160;&gt;@@g' html/*.html
-	gsed -i 's@&lt; ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType &gt;@@g' html/*.html
-	gsed -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType >@@g' html/*.html
+	$(SED) -i 's@&lt; ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType &gt;@@g' html/*.html
+	$(SED) -i 's@&lt;&#160;ObjectType,&#160;ArrayType,&#160;StringType,&#160;BooleanType,&#160;NumberIntegerType,&#160;NumberFloatType,&#160;AllocatorType&#160;&gt;@@g' html/*.html
+	$(SED) -i 's@&lt; ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType &gt;@@g' html/*.html
+	$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType >@@g' html/*.html
 
 upload: clean doxygen check_output
 	cd html ; ../scripts/git-update-ghpages nlohmann/json
@@ -70,14 +71,14 @@ upload: clean doxygen check_output
 # create docset for Dash
 docset: create_output
 	cp Doxyfile Doxyfile_docset
-	gsed -i 's/DISABLE_INDEX          = NO/DISABLE_INDEX          = YES/' Doxyfile_docset
-	gsed -i 's/SEARCHENGINE           = YES/SEARCHENGINE           = NO/' Doxyfile_docset
-	gsed -i 's@HTML_EXTRA_STYLESHEET  = css/mylayout.css@HTML_EXTRA_STYLESHEET  = css/mylayout_docset.css@' Doxyfile_docset
+	$(SED) -i 's/DISABLE_INDEX          = NO/DISABLE_INDEX          = YES/' Doxyfile_docset
+	$(SED) -i 's/SEARCHENGINE           = YES/SEARCHENGINE           = NO/' Doxyfile_docset
+	$(SED) -i 's@HTML_EXTRA_STYLESHEET  = css/mylayout.css@HTML_EXTRA_STYLESHEET  = css/mylayout_docset.css@' Doxyfile_docset
 	rm -fr html *.docset
 	doxygen Doxyfile_docset
-	gsed -i 's@&lt; ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType &gt;@@g' html/*.html
-	gsed -i 's@&lt;&#160;ObjectType,&#160;ArrayType,&#160;StringType,&#160;BooleanType,&#160;NumberIntegerType,&#160;NumberFloatType,&#160;AllocatorType&#160;&gt;@@g' html/*.html
+	$(SED) -i 's@&lt; ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType &gt;@@g' html/*.html
+	$(SED) -i 's@&lt;&#160;ObjectType,&#160;ArrayType,&#160;StringType,&#160;BooleanType,&#160;NumberIntegerType,&#160;NumberFloatType,&#160;AllocatorType&#160;&gt;@@g' html/*.html
 	make -C html
 	mv html/*.docset .
-	gsed -i 's@<string>doxygen</string>@<string>json</string>@' me.nlohmann.json.docset/Contents/Info.plist
+	$(SED) -i 's@<string>doxygen</string>@<string>json</string>@' me.nlohmann.json.docset/Contents/Info.plist
 	rm -fr Doxyfile_docset html

From 7f4dd5d6088b7f1cb95acb31d8c4f31503193b64 Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Fri, 15 Jul 2016 19:44:19 +0200
Subject: [PATCH 27/31] added header for int64_t and uint64_t (fixes #282)

---
 src/json.hpp      | 1 +
 src/json.hpp.re2c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/json.hpp b/src/json.hpp
index ba7d8212..44c867c0 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -37,6 +37,7 @@ SOFTWARE.
 #include <cmath>
 #include <cstddef>
 #include <cstdio>
+#include <cstdint>
 #include <cstdlib>
 #include <functional>
 #include <initializer_list>
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 5ee270f9..dffce54c 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -37,6 +37,7 @@ SOFTWARE.
 #include <cmath>
 #include <cstddef>
 #include <cstdio>
+#include <cstdint>
 #include <cstdlib>
 #include <functional>
 #include <initializer_list>

From b64367e2f76aa38f6a745e7167fc93fb1c9183fb Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Mon, 18 Jul 2016 16:22:10 +0200
Subject: [PATCH 28/31] fix for #279

---
 doc/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/Makefile b/doc/Makefile
index 1fb17cfc..56198923 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,5 +1,5 @@
 SRCDIR = ../src
-SED:=$(shell command -v sed || gsed)
+SED:=$(shell command -v gsed || which sed)
 
 all: doxygen
 

From 2478be807c8b3fb28674fa2fb63a5e1263ea3c4a Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 19 Jul 2016 22:10:27 +0200
Subject: [PATCH 29/31] avoid recursion in the scanner

---
 src/json.hpp      | 1256 +++++++++++++++++++++++----------------------
 src/json.hpp.re2c |  127 ++---
 2 files changed, 705 insertions(+), 678 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 44c867c0..1311080b 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -7393,400 +7393,402 @@ class basic_json
         */
         token_type scan() noexcept
         {
-            // pointer for backtracking information
-            m_marker = nullptr;
-
-            // remember the begin of the token
-            m_start = m_cursor;
-            assert(m_start != nullptr);
-
-
+            while (true)
             {
-                lexer_char_t yych;
-                unsigned int yyaccept = 0;
-                static const unsigned char yybm[] =
+                // pointer for backtracking information
+                m_marker = nullptr;
+
+                // remember the begin of the token
+                m_start = m_cursor;
+                assert(m_start != nullptr);
+
+
                 {
-                    0,   0,   0,   0,   0,   0,   0,   0,
-                    0,  32,  32,   0,   0,  32,   0,   0,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    160, 128,   0, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    192, 192, 192, 192, 192, 192, 192, 192,
-                    192, 192, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128,   0, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                };
-                if ((m_limit - m_cursor) < 5)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yybm[0 + yych] & 32)
-                {
-                    goto basic_json_parser_6;
-                }
-                if (yych <= '\\')
-                {
-                    if (yych <= '-')
+                    lexer_char_t yych;
+                    unsigned int yyaccept = 0;
+                    static const unsigned char yybm[] =
                     {
-                        if (yych <= '"')
+                        0,   0,   0,   0,   0,   0,   0,   0,
+                        0,  32,  32,   0,   0,  32,   0,   0,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        160, 128,   0, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        192, 192, 192, 192, 192, 192, 192, 192,
+                        192, 192, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128,   0, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                    };
+                    if ((m_limit - m_cursor) < 5)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yybm[0 + yych] & 32)
+                    {
+                        goto basic_json_parser_6;
+                    }
+                    if (yych <= '\\')
+                    {
+                        if (yych <= '-')
                         {
-                            if (yych <= 0x00)
+                            if (yych <= '"')
                             {
-                                goto basic_json_parser_2;
+                                if (yych <= 0x00)
+                                {
+                                    goto basic_json_parser_2;
+                                }
+                                if (yych <= '!')
+                                {
+                                    goto basic_json_parser_4;
+                                }
+                                goto basic_json_parser_9;
                             }
-                            if (yych <= '!')
+                            else
                             {
-                                goto basic_json_parser_4;
+                                if (yych <= '+')
+                                {
+                                    goto basic_json_parser_4;
+                                }
+                                if (yych <= ',')
+                                {
+                                    goto basic_json_parser_10;
+                                }
+                                goto basic_json_parser_12;
                             }
-                            goto basic_json_parser_9;
                         }
                         else
                         {
-                            if (yych <= '+')
+                            if (yych <= '9')
                             {
+                                if (yych <= '/')
+                                {
+                                    goto basic_json_parser_4;
+                                }
+                                if (yych <= '0')
+                                {
+                                    goto basic_json_parser_13;
+                                }
+                                goto basic_json_parser_15;
+                            }
+                            else
+                            {
+                                if (yych <= ':')
+                                {
+                                    goto basic_json_parser_17;
+                                }
+                                if (yych == '[')
+                                {
+                                    goto basic_json_parser_19;
+                                }
                                 goto basic_json_parser_4;
                             }
-                            if (yych <= ',')
-                            {
-                                goto basic_json_parser_10;
-                            }
-                            goto basic_json_parser_12;
                         }
                     }
                     else
                     {
-                        if (yych <= '9')
+                        if (yych <= 't')
                         {
-                            if (yych <= '/')
+                            if (yych <= 'f')
                             {
-                                goto basic_json_parser_4;
+                                if (yych <= ']')
+                                {
+                                    goto basic_json_parser_21;
+                                }
+                                if (yych <= 'e')
+                                {
+                                    goto basic_json_parser_4;
+                                }
+                                goto basic_json_parser_23;
                             }
-                            if (yych <= '0')
+                            else
                             {
-                                goto basic_json_parser_13;
+                                if (yych == 'n')
+                                {
+                                    goto basic_json_parser_24;
+                                }
+                                if (yych <= 's')
+                                {
+                                    goto basic_json_parser_4;
+                                }
+                                goto basic_json_parser_25;
                             }
-                            goto basic_json_parser_15;
                         }
                         else
                         {
-                            if (yych <= ':')
-                            {
-                                goto basic_json_parser_17;
-                            }
-                            if (yych == '[')
-                            {
-                                goto basic_json_parser_19;
-                            }
-                            goto basic_json_parser_4;
-                        }
-                    }
-                }
-                else
-                {
-                    if (yych <= 't')
-                    {
-                        if (yych <= 'f')
-                        {
-                            if (yych <= ']')
-                            {
-                                goto basic_json_parser_21;
-                            }
-                            if (yych <= 'e')
+                            if (yych <= '|')
                             {
+                                if (yych == '{')
+                                {
+                                    goto basic_json_parser_26;
+                                }
                                 goto basic_json_parser_4;
                             }
-                            goto basic_json_parser_23;
-                        }
-                        else
-                        {
-                            if (yych == 'n')
-                            {
-                                goto basic_json_parser_24;
-                            }
-                            if (yych <= 's')
+                            else
                             {
+                                if (yych <= '}')
+                                {
+                                    goto basic_json_parser_28;
+                                }
+                                if (yych == 0xEF)
+                                {
+                                    goto basic_json_parser_30;
+                                }
                                 goto basic_json_parser_4;
                             }
-                            goto basic_json_parser_25;
                         }
                     }
-                    else
-                    {
-                        if (yych <= '|')
-                        {
-                            if (yych == '{')
-                            {
-                                goto basic_json_parser_26;
-                            }
-                            goto basic_json_parser_4;
-                        }
-                        else
-                        {
-                            if (yych <= '}')
-                            {
-                                goto basic_json_parser_28;
-                            }
-                            if (yych == 0xEF)
-                            {
-                                goto basic_json_parser_30;
-                            }
-                            goto basic_json_parser_4;
-                        }
-                    }
-                }
 basic_json_parser_2:
-                ++m_cursor;
-                {
-                    return token_type::end_of_input;
-                }
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::end_of_input;
+                        break;
+                    }
 basic_json_parser_4:
-                ++m_cursor;
+                    ++m_cursor;
 basic_json_parser_5:
-                {
-                    return token_type::parse_error;
-                }
+                    {
+                        last_token_type = token_type::parse_error;
+                        break;
+                    }
 basic_json_parser_6:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yybm[0 + yych] & 32)
-                {
-                    goto basic_json_parser_6;
-                }
-                {
-                    return scan();
-                }
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yybm[0 + yych] & 32)
+                    {
+                        goto basic_json_parser_6;
+                    }
+                    {
+                        continue;
+                    }
 basic_json_parser_9:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych <= 0x0F)
-                {
-                    goto basic_json_parser_5;
-                }
-                goto basic_json_parser_32;
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych <= 0x0F)
+                    {
+                        goto basic_json_parser_5;
+                    }
+                    goto basic_json_parser_32;
 basic_json_parser_10:
-                ++m_cursor;
-                {
-                    return token_type::value_separator;
-                }
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::value_separator;
+                        break;
+                    }
 basic_json_parser_12:
-                yych = *++m_cursor;
-                if (yych <= '/')
-                {
-                    goto basic_json_parser_5;
-                }
-                if (yych <= '0')
-                {
-                    goto basic_json_parser_13;
-                }
-                if (yych <= '9')
-                {
-                    goto basic_json_parser_15;
-                }
-                goto basic_json_parser_5;
-basic_json_parser_13:
-                yyaccept = 1;
-                yych = *(m_marker = ++m_cursor);
-                if (yych <= 'D')
-                {
-                    if (yych == '.')
-                    {
-                        goto basic_json_parser_37;
-                    }
-                }
-                else
-                {
-                    if (yych <= 'E')
-                    {
-                        goto basic_json_parser_38;
-                    }
-                    if (yych == 'e')
-                    {
-                        goto basic_json_parser_38;
-                    }
-                }
-basic_json_parser_14:
-                {
-                    return token_type::value_number;
-                }
-basic_json_parser_15:
-                yyaccept = 1;
-                m_marker = ++m_cursor;
-                if ((m_limit - m_cursor) < 3)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yybm[0 + yych] & 64)
-                {
-                    goto basic_json_parser_15;
-                }
-                if (yych <= 'D')
-                {
-                    if (yych == '.')
-                    {
-                        goto basic_json_parser_37;
-                    }
-                    goto basic_json_parser_14;
-                }
-                else
-                {
-                    if (yych <= 'E')
-                    {
-                        goto basic_json_parser_38;
-                    }
-                    if (yych == 'e')
-                    {
-                        goto basic_json_parser_38;
-                    }
-                    goto basic_json_parser_14;
-                }
-basic_json_parser_17:
-                ++m_cursor;
-                {
-                    return token_type::name_separator;
-                }
-basic_json_parser_19:
-                ++m_cursor;
-                {
-                    return token_type::begin_array;
-                }
-basic_json_parser_21:
-                ++m_cursor;
-                {
-                    return token_type::end_array;
-                }
-basic_json_parser_23:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 'a')
-                {
-                    goto basic_json_parser_39;
-                }
-                goto basic_json_parser_5;
-basic_json_parser_24:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 'u')
-                {
-                    goto basic_json_parser_40;
-                }
-                goto basic_json_parser_5;
-basic_json_parser_25:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 'r')
-                {
-                    goto basic_json_parser_41;
-                }
-                goto basic_json_parser_5;
-basic_json_parser_26:
-                ++m_cursor;
-                {
-                    return token_type::begin_object;
-                }
-basic_json_parser_28:
-                ++m_cursor;
-                {
-                    return token_type::end_object;
-                }
-basic_json_parser_30:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 0xBB)
-                {
-                    goto basic_json_parser_42;
-                }
-                goto basic_json_parser_5;
-basic_json_parser_31:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-basic_json_parser_32:
-                if (yybm[0 + yych] & 128)
-                {
-                    goto basic_json_parser_31;
-                }
-                if (yych <= 0x0F)
-                {
-                    goto basic_json_parser_33;
-                }
-                if (yych <= '"')
-                {
-                    goto basic_json_parser_34;
-                }
-                goto basic_json_parser_36;
-basic_json_parser_33:
-                m_cursor = m_marker;
-                if (yyaccept == 0)
-                {
-                    goto basic_json_parser_5;
-                }
-                else
-                {
-                    goto basic_json_parser_14;
-                }
-basic_json_parser_34:
-                ++m_cursor;
-                {
-                    return token_type::value_string;
-                }
-basic_json_parser_36:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= 'e')
-                {
+                    yych = *++m_cursor;
                     if (yych <= '/')
                     {
-                        if (yych == '"')
+                        goto basic_json_parser_5;
+                    }
+                    if (yych <= '0')
+                    {
+                        goto basic_json_parser_13;
+                    }
+                    if (yych <= '9')
+                    {
+                        goto basic_json_parser_15;
+                    }
+                    goto basic_json_parser_5;
+basic_json_parser_13:
+                    yyaccept = 1;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych <= 'D')
+                    {
+                        if (yych == '.')
                         {
-                            goto basic_json_parser_31;
+                            goto basic_json_parser_37;
                         }
-                        if (yych <= '.')
-                        {
-                            goto basic_json_parser_33;
-                        }
-                        goto basic_json_parser_31;
                     }
                     else
                     {
-                        if (yych <= '\\')
+                        if (yych <= 'E')
                         {
-                            if (yych <= '[')
+                            goto basic_json_parser_38;
+                        }
+                        if (yych == 'e')
+                        {
+                            goto basic_json_parser_38;
+                        }
+                    }
+basic_json_parser_14:
+                    {
+                        last_token_type = token_type::value_number;
+                        break;
+                    }
+basic_json_parser_15:
+                    yyaccept = 1;
+                    m_marker = ++m_cursor;
+                    if ((m_limit - m_cursor) < 3)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yybm[0 + yych] & 64)
+                    {
+                        goto basic_json_parser_15;
+                    }
+                    if (yych <= 'D')
+                    {
+                        if (yych == '.')
+                        {
+                            goto basic_json_parser_37;
+                        }
+                        goto basic_json_parser_14;
+                    }
+                    else
+                    {
+                        if (yych <= 'E')
+                        {
+                            goto basic_json_parser_38;
+                        }
+                        if (yych == 'e')
+                        {
+                            goto basic_json_parser_38;
+                        }
+                        goto basic_json_parser_14;
+                    }
+basic_json_parser_17:
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::name_separator;
+                        break;
+                    }
+basic_json_parser_19:
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::begin_array;
+                        break;
+                    }
+basic_json_parser_21:
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::end_array;
+                        break;
+                    }
+basic_json_parser_23:
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych == 'a')
+                    {
+                        goto basic_json_parser_39;
+                    }
+                    goto basic_json_parser_5;
+basic_json_parser_24:
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych == 'u')
+                    {
+                        goto basic_json_parser_40;
+                    }
+                    goto basic_json_parser_5;
+basic_json_parser_25:
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych == 'r')
+                    {
+                        goto basic_json_parser_41;
+                    }
+                    goto basic_json_parser_5;
+basic_json_parser_26:
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::begin_object;
+                        break;
+                    }
+basic_json_parser_28:
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::end_object;
+                        break;
+                    }
+basic_json_parser_30:
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych == 0xBB)
+                    {
+                        goto basic_json_parser_42;
+                    }
+                    goto basic_json_parser_5;
+basic_json_parser_31:
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+basic_json_parser_32:
+                    if (yybm[0 + yych] & 128)
+                    {
+                        goto basic_json_parser_31;
+                    }
+                    if (yych <= 0x0F)
+                    {
+                        goto basic_json_parser_33;
+                    }
+                    if (yych <= '"')
+                    {
+                        goto basic_json_parser_34;
+                    }
+                    goto basic_json_parser_36;
+basic_json_parser_33:
+                    m_cursor = m_marker;
+                    if (yyaccept == 0)
+                    {
+                        goto basic_json_parser_5;
+                    }
+                    else
+                    {
+                        goto basic_json_parser_14;
+                    }
+basic_json_parser_34:
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::value_string;
+                        break;
+                    }
+basic_json_parser_36:
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yych <= 'e')
+                    {
+                        if (yych <= '/')
+                        {
+                            if (yych == '"')
+                            {
+                                goto basic_json_parser_31;
+                            }
+                            if (yych <= '.')
                             {
                                 goto basic_json_parser_33;
                             }
@@ -7794,33 +7796,33 @@ basic_json_parser_36:
                         }
                         else
                         {
-                            if (yych == 'b')
+                            if (yych <= '\\')
                             {
+                                if (yych <= '[')
+                                {
+                                    goto basic_json_parser_33;
+                                }
                                 goto basic_json_parser_31;
                             }
-                            goto basic_json_parser_33;
+                            else
+                            {
+                                if (yych == 'b')
+                                {
+                                    goto basic_json_parser_31;
+                                }
+                                goto basic_json_parser_33;
+                            }
                         }
                     }
-                }
-                else
-                {
-                    if (yych <= 'q')
-                    {
-                        if (yych <= 'f')
-                        {
-                            goto basic_json_parser_31;
-                        }
-                        if (yych == 'n')
-                        {
-                            goto basic_json_parser_31;
-                        }
-                        goto basic_json_parser_33;
-                    }
                     else
                     {
-                        if (yych <= 's')
+                        if (yych <= 'q')
                         {
-                            if (yych <= 'r')
+                            if (yych <= 'f')
+                            {
+                                goto basic_json_parser_31;
+                            }
+                            if (yych == 'n')
                             {
                                 goto basic_json_parser_31;
                             }
@@ -7828,331 +7830,347 @@ basic_json_parser_36:
                         }
                         else
                         {
-                            if (yych <= 't')
+                            if (yych <= 's')
                             {
-                                goto basic_json_parser_31;
+                                if (yych <= 'r')
+                                {
+                                    goto basic_json_parser_31;
+                                }
+                                goto basic_json_parser_33;
                             }
-                            if (yych <= 'u')
+                            else
                             {
-                                goto basic_json_parser_43;
+                                if (yych <= 't')
+                                {
+                                    goto basic_json_parser_31;
+                                }
+                                if (yych <= 'u')
+                                {
+                                    goto basic_json_parser_43;
+                                }
+                                goto basic_json_parser_33;
                             }
-                            goto basic_json_parser_33;
                         }
                     }
-                }
 basic_json_parser_37:
-                yych = *++m_cursor;
-                if (yych <= '/')
-                {
+                    yych = *++m_cursor;
+                    if (yych <= '/')
+                    {
+                        goto basic_json_parser_33;
+                    }
+                    if (yych <= '9')
+                    {
+                        goto basic_json_parser_44;
+                    }
                     goto basic_json_parser_33;
-                }
-                if (yych <= '9')
-                {
-                    goto basic_json_parser_44;
-                }
-                goto basic_json_parser_33;
 basic_json_parser_38:
-                yych = *++m_cursor;
-                if (yych <= ',')
-                {
-                    if (yych == '+')
-                    {
-                        goto basic_json_parser_46;
-                    }
-                    goto basic_json_parser_33;
-                }
-                else
-                {
-                    if (yych <= '-')
-                    {
-                        goto basic_json_parser_46;
-                    }
-                    if (yych <= '/')
+                    yych = *++m_cursor;
+                    if (yych <= ',')
                     {
+                        if (yych == '+')
+                        {
+                            goto basic_json_parser_46;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= '9')
+                    else
                     {
-                        goto basic_json_parser_47;
+                        if (yych <= '-')
+                        {
+                            goto basic_json_parser_46;
+                        }
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_47;
+                        }
+                        goto basic_json_parser_33;
                     }
-                    goto basic_json_parser_33;
-                }
 basic_json_parser_39:
-                yych = *++m_cursor;
-                if (yych == 'l')
-                {
-                    goto basic_json_parser_49;
-                }
-                goto basic_json_parser_33;
+                    yych = *++m_cursor;
+                    if (yych == 'l')
+                    {
+                        goto basic_json_parser_49;
+                    }
+                    goto basic_json_parser_33;
 basic_json_parser_40:
-                yych = *++m_cursor;
-                if (yych == 'l')
-                {
-                    goto basic_json_parser_50;
-                }
-                goto basic_json_parser_33;
+                    yych = *++m_cursor;
+                    if (yych == 'l')
+                    {
+                        goto basic_json_parser_50;
+                    }
+                    goto basic_json_parser_33;
 basic_json_parser_41:
-                yych = *++m_cursor;
-                if (yych == 'u')
-                {
-                    goto basic_json_parser_51;
-                }
-                goto basic_json_parser_33;
+                    yych = *++m_cursor;
+                    if (yych == 'u')
+                    {
+                        goto basic_json_parser_51;
+                    }
+                    goto basic_json_parser_33;
 basic_json_parser_42:
-                yych = *++m_cursor;
-                if (yych == 0xBF)
-                {
-                    goto basic_json_parser_52;
-                }
-                goto basic_json_parser_33;
+                    yych = *++m_cursor;
+                    if (yych == 0xBF)
+                    {
+                        goto basic_json_parser_52;
+                    }
+                    goto basic_json_parser_33;
 basic_json_parser_43:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yych <= '@')
+                    {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_54;
+                        }
+                        goto basic_json_parser_33;
+                    }
+                    else
+                    {
+                        if (yych <= 'F')
+                        {
+                            goto basic_json_parser_54;
+                        }
+                        if (yych <= '`')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= 'f')
+                        {
+                            goto basic_json_parser_54;
+                        }
+                        goto basic_json_parser_33;
+                    }
+basic_json_parser_44:
+                    yyaccept = 1;
+                    m_marker = ++m_cursor;
+                    if ((m_limit - m_cursor) < 3)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yych <= 'D')
+                    {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_14;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_44;
+                        }
+                        goto basic_json_parser_14;
+                    }
+                    else
+                    {
+                        if (yych <= 'E')
+                        {
+                            goto basic_json_parser_38;
+                        }
+                        if (yych == 'e')
+                        {
+                            goto basic_json_parser_38;
+                        }
+                        goto basic_json_parser_14;
+                    }
+basic_json_parser_46:
+                    yych = *++m_cursor;
                     if (yych <= '/')
                     {
                         goto basic_json_parser_33;
                     }
-                    if (yych <= '9')
-                    {
-                        goto basic_json_parser_54;
-                    }
-                    goto basic_json_parser_33;
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto basic_json_parser_54;
-                    }
-                    if (yych <= '`')
+                    if (yych >= ':')
                     {
                         goto basic_json_parser_33;
                     }
-                    if (yych <= 'f')
+basic_json_parser_47:
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
                     {
-                        goto basic_json_parser_54;
+                        yyfill();    // LCOV_EXCL_LINE;
                     }
-                    goto basic_json_parser_33;
-                }
-basic_json_parser_44:
-                yyaccept = 1;
-                m_marker = ++m_cursor;
-                if ((m_limit - m_cursor) < 3)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= 'D')
-                {
+                    yych = *m_cursor;
                     if (yych <= '/')
                     {
                         goto basic_json_parser_14;
                     }
                     if (yych <= '9')
                     {
-                        goto basic_json_parser_44;
+                        goto basic_json_parser_47;
                     }
                     goto basic_json_parser_14;
-                }
-                else
-                {
-                    if (yych <= 'E')
+basic_json_parser_49:
+                    yych = *++m_cursor;
+                    if (yych == 's')
                     {
-                        goto basic_json_parser_38;
+                        goto basic_json_parser_55;
                     }
+                    goto basic_json_parser_33;
+basic_json_parser_50:
+                    yych = *++m_cursor;
+                    if (yych == 'l')
+                    {
+                        goto basic_json_parser_56;
+                    }
+                    goto basic_json_parser_33;
+basic_json_parser_51:
+                    yych = *++m_cursor;
                     if (yych == 'e')
                     {
-                        goto basic_json_parser_38;
+                        goto basic_json_parser_58;
                     }
-                    goto basic_json_parser_14;
-                }
-basic_json_parser_46:
-                yych = *++m_cursor;
-                if (yych <= '/')
-                {
                     goto basic_json_parser_33;
-                }
-                if (yych >= ':')
-                {
-                    goto basic_json_parser_33;
-                }
-basic_json_parser_47:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '/')
-                {
-                    goto basic_json_parser_14;
-                }
-                if (yych <= '9')
-                {
-                    goto basic_json_parser_47;
-                }
-                goto basic_json_parser_14;
-basic_json_parser_49:
-                yych = *++m_cursor;
-                if (yych == 's')
-                {
-                    goto basic_json_parser_55;
-                }
-                goto basic_json_parser_33;
-basic_json_parser_50:
-                yych = *++m_cursor;
-                if (yych == 'l')
-                {
-                    goto basic_json_parser_56;
-                }
-                goto basic_json_parser_33;
-basic_json_parser_51:
-                yych = *++m_cursor;
-                if (yych == 'e')
-                {
-                    goto basic_json_parser_58;
-                }
-                goto basic_json_parser_33;
 basic_json_parser_52:
-                ++m_cursor;
-                {
-                    return scan();
-                }
+                    ++m_cursor;
+                    {
+                        continue;
+                    }
 basic_json_parser_54:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
-                    if (yych <= '/')
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
                     {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yych <= '@')
+                    {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_60;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= '9')
-                    {
-                        goto basic_json_parser_60;
-                    }
-                    goto basic_json_parser_33;
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto basic_json_parser_60;
-                    }
-                    if (yych <= '`')
+                    else
                     {
+                        if (yych <= 'F')
+                        {
+                            goto basic_json_parser_60;
+                        }
+                        if (yych <= '`')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= 'f')
+                        {
+                            goto basic_json_parser_60;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= 'f')
-                    {
-                        goto basic_json_parser_60;
-                    }
-                    goto basic_json_parser_33;
-                }
 basic_json_parser_55:
-                yych = *++m_cursor;
-                if (yych == 'e')
-                {
-                    goto basic_json_parser_61;
-                }
-                goto basic_json_parser_33;
+                    yych = *++m_cursor;
+                    if (yych == 'e')
+                    {
+                        goto basic_json_parser_61;
+                    }
+                    goto basic_json_parser_33;
 basic_json_parser_56:
-                ++m_cursor;
-                {
-                    return token_type::literal_null;
-                }
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::literal_null;
+                        break;
+                    }
 basic_json_parser_58:
-                ++m_cursor;
-                {
-                    return token_type::literal_true;
-                }
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::literal_true;
+                        break;
+                    }
 basic_json_parser_60:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
-                    if (yych <= '/')
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
                     {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yych <= '@')
+                    {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_63;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= '9')
-                    {
-                        goto basic_json_parser_63;
-                    }
-                    goto basic_json_parser_33;
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto basic_json_parser_63;
-                    }
-                    if (yych <= '`')
+                    else
                     {
+                        if (yych <= 'F')
+                        {
+                            goto basic_json_parser_63;
+                        }
+                        if (yych <= '`')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= 'f')
+                        {
+                            goto basic_json_parser_63;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= 'f')
-                    {
-                        goto basic_json_parser_63;
-                    }
-                    goto basic_json_parser_33;
-                }
 basic_json_parser_61:
-                ++m_cursor;
-                {
-                    return token_type::literal_false;
-                }
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::literal_false;
+                        break;
+                    }
 basic_json_parser_63:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
-                    if (yych <= '/')
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
                     {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yych <= '@')
+                    {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_31;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= '9')
-                    {
-                        goto basic_json_parser_31;
-                    }
-                    goto basic_json_parser_33;
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto basic_json_parser_31;
-                    }
-                    if (yych <= '`')
+                    else
                     {
+                        if (yych <= 'F')
+                        {
+                            goto basic_json_parser_31;
+                        }
+                        if (yych <= '`')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= 'f')
+                        {
+                            goto basic_json_parser_31;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= 'f')
-                    {
-                        goto basic_json_parser_31;
-                    }
-                    goto basic_json_parser_33;
                 }
+
             }
 
+            return last_token_type;
         }
 
         /// append data from the stream to the internal buffer
@@ -8500,6 +8518,8 @@ basic_json_parser_63:
         const lexer_char_t* m_cursor = nullptr;
         /// pointer to the end of the buffer
         const lexer_char_t* m_limit = nullptr;
+        /// the last token type
+        token_type last_token_type = token_type::end_of_input;
     };
 
     /*!
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index dffce54c..a65e41bf 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -7393,76 +7393,81 @@ class basic_json
         */
         token_type scan() noexcept
         {
-            // pointer for backtracking information
-            m_marker = nullptr;
+            while (true)
+            {
+                // pointer for backtracking information
+                m_marker = nullptr;
 
-            // remember the begin of the token
-            m_start = m_cursor;
-            assert(m_start != nullptr);
+                // remember the begin of the token
+                m_start = m_cursor;
+                assert(m_start != nullptr);
 
-            /*!re2c
-                re2c:define:YYCTYPE   = lexer_char_t;
-                re2c:define:YYCURSOR  = m_cursor;
-                re2c:define:YYLIMIT   = m_limit;
-                re2c:define:YYMARKER  = m_marker;
-                re2c:define:YYFILL    = "yyfill(); // LCOV_EXCL_LINE";
-                re2c:yyfill:parameter = 0;
-                re2c:indent:string    = "    ";
-                re2c:indent:top       = 1;
-                re2c:labelprefix      = "basic_json_parser_";
+                /*!re2c
+                    re2c:define:YYCTYPE   = lexer_char_t;
+                    re2c:define:YYCURSOR  = m_cursor;
+                    re2c:define:YYLIMIT   = m_limit;
+                    re2c:define:YYMARKER  = m_marker;
+                    re2c:define:YYFILL    = "yyfill(); // LCOV_EXCL_LINE";
+                    re2c:yyfill:parameter = 0;
+                    re2c:indent:string    = "    ";
+                    re2c:indent:top       = 1;
+                    re2c:labelprefix      = "basic_json_parser_";
 
-                // ignore whitespace
-                ws = [ \t\n\r]+;
-                ws   { return scan(); }
+                    // ignore whitespace
+                    ws = [ \t\n\r]+;
+                    ws   { continue; }
 
-                // ignore byte-order-mark
-                bom = "\xEF\xBB\xBF";
-                bom   { return scan(); }
+                    // ignore byte-order-mark
+                    bom = "\xEF\xBB\xBF";
+                    bom   { continue; }
 
-                // structural characters
-                "[" { return token_type::begin_array; }
-                "]" { return token_type::end_array; }
-                "{" { return token_type::begin_object; }
-                "}" { return token_type::end_object; }
-                "," { return token_type::value_separator; }
-                ":" { return token_type::name_separator; }
+                    // structural characters
+                    "[" { last_token_type = token_type::begin_array; break; }
+                    "]" { last_token_type = token_type::end_array; break; }
+                    "{" { last_token_type = token_type::begin_object; break; }
+                    "}" { last_token_type = token_type::end_object; break; }
+                    "," { last_token_type = token_type::value_separator; break; }
+                    ":" { last_token_type = token_type::name_separator; break; }
 
-                // literal names
-                "null"  { return token_type::literal_null; }
-                "true"  { return token_type::literal_true; }
-                "false" { return token_type::literal_false; }
+                    // literal names
+                    "null"  { last_token_type = token_type::literal_null; break; }
+                    "true"  { last_token_type = token_type::literal_true; break; }
+                    "false" { last_token_type = token_type::literal_false; break; }
 
-                // number
-                decimal_point = [.];
-                digit         = [0-9];
-                digit_1_9     = [1-9];
-                e             = [eE];
-                minus         = [-];
-                plus          = [+];
-                zero          = [0];
-                exp           = e (minus|plus)? digit+;
-                frac          = decimal_point digit+;
-                int           = (zero|digit_1_9 digit*);
-                number        = minus? int frac? exp?;
-                number        { return token_type::value_number; }
+                    // number
+                    decimal_point = [.];
+                    digit         = [0-9];
+                    digit_1_9     = [1-9];
+                    e             = [eE];
+                    minus         = [-];
+                    plus          = [+];
+                    zero          = [0];
+                    exp           = e (minus|plus)? digit+;
+                    frac          = decimal_point digit+;
+                    int           = (zero|digit_1_9 digit*);
+                    number        = minus? int frac? exp?;
+                    number        { last_token_type = token_type::value_number; break; }
 
-                // string
-                quotation_mark  = ["];
-                escape          = [\\];
-                unescaped       = [^"\\\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F];
-                single_escaped  = ["\\/bfnrt];
-                unicode_escaped = [u][0-9a-fA-F]{4};
-                escaped         = escape (single_escaped | unicode_escaped);
-                char            = unescaped | escaped;
-                string          = quotation_mark char* quotation_mark;
-                string          { return token_type::value_string; }
+                    // string
+                    quotation_mark  = ["];
+                    escape          = [\\];
+                    unescaped       = [^"\\\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F];
+                    single_escaped  = ["\\/bfnrt];
+                    unicode_escaped = [u][0-9a-fA-F]{4};
+                    escaped         = escape (single_escaped | unicode_escaped);
+                    char            = unescaped | escaped;
+                    string          = quotation_mark char* quotation_mark;
+                    string          { last_token_type = token_type::value_string; break; }
 
-                // end of file
-                '\000'         { return token_type::end_of_input; }
+                    // end of file
+                    '\000'         { last_token_type = token_type::end_of_input; break; }
 
-                // anything else is an error
-                .              { return token_type::parse_error; }
-            */
+                    // anything else is an error
+                    .              { last_token_type = token_type::parse_error; break; }
+                */
+            }
+
+            return last_token_type;
         }
 
         /// append data from the stream to the internal buffer
@@ -7810,6 +7815,8 @@ class basic_json
         const lexer_char_t* m_cursor = nullptr;
         /// pointer to the end of the buffer
         const lexer_char_t* m_limit = nullptr;
+        /// the last token type
+        token_type last_token_type = token_type::end_of_input;
     };
 
     /*!

From 0f834056bb06a4859f64d7b2457849449df6f2bc Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 19 Jul 2016 22:17:43 +0200
Subject: [PATCH 30/31] removed unused header

---
 src/json.hpp      | 1 -
 src/json.hpp.re2c | 1 -
 2 files changed, 2 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 1311080b..fa14b0e7 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -36,7 +36,6 @@ SOFTWARE.
 #include <ciso646>
 #include <cmath>
 #include <cstddef>
-#include <cstdio>
 #include <cstdint>
 #include <cstdlib>
 #include <functional>
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index a65e41bf..dd1bda1f 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -36,7 +36,6 @@ SOFTWARE.
 #include <ciso646>
 #include <cmath>
 #include <cstddef>
-#include <cstdio>
 #include <cstdint>
 #include <cstdlib>
 #include <functional>

From cb145cfe714769266913a2ff623b9b643984a78f Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Tue, 19 Jul 2016 22:43:56 +0200
Subject: [PATCH 31/31] updated Changelog

---
 ChangeLog.md | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/ChangeLog.md b/ChangeLog.md
index 34d28e4d..e3a7cc07 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,6 +1,17 @@
 # Change Log
 All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
 
+## [Unreleased](https://github.com/nlohmann/json/tree/HEAD)
+
+[Full Changelog](https://github.com/nlohmann/json/compare/v2.0.1...HEAD)
+
+- Build error for std::int64 [\#282](https://github.com/nlohmann/json/issues/282)
+
+- hexify\(\) function emits conversion warning [\#270](https://github.com/nlohmann/json/issues/270)
+
+- let the makefile choose the correct sed [\#279](https://github.com/nlohmann/json/pull/279) ([murinicanor](https://github.com/murinicanor))
+- Update hexify to use array lookup instead of ternary \(\#270\) [\#275](https://github.com/nlohmann/json/pull/275) ([dtoma](https://github.com/dtoma))
+
 ## [v2.0.1](https://github.com/nlohmann/json/releases/tag/v2.0.1) (2016-06-28)
 [Full Changelog](https://github.com/nlohmann/json/compare/v2.0.0...v2.0.1)