From ca2bbdb15b761184744db4c46fdc3167d620a26f Mon Sep 17 00:00:00 2001 From: Niels 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 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?= 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 c_map { {"one", 1}, {"two", 2}, {"three", 3} }; From c74b9ff4f7d5d0e11f711292165f17423d8233f1 Mon Sep 17 00:00:00 2001 From: Niels 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 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 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(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::digits10 - std::stringstream ss; - ss.imbue(std::locale(std::locale(), new DecimalSeparator)); // fix locale problems - ss << std::setprecision(std::numeric_limits::digits10) - << m_value.number_float; - o << ss.str(); + o << std::setprecision(std::numeric_limits::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(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::digits10 - std::stringstream ss; - ss.imbue(std::locale(std::locale(), new DecimalSeparator)); // fix locale problems - ss << std::setprecision(std::numeric_limits::digits10) - << m_value.number_float; - o << ss.str(); + o << std::setprecision(std::numeric_limits::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 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(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(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 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 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 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 . 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 . 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 . From 7ffa07e3a3b21a2fec08da9c7d4fda8b7d043ff9 Mon Sep 17 00:00:00 2001 From: Niels 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 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 #include +// 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 #include +// 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 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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 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 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 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 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 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 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(v)) - : ('a' + static_cast((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 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 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 @@ -online \ No newline at end of file +online \ 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 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 +struct DecimalSeparator : std::numpunct { - 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; 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::type>::type>::type; + // make sure the type matches the allowed types + static_assert( + std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + , "incompatible pointer type"); + // delegate the call to get_impl_ptr<>() return get_impl_ptr(static_cast(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::type>::type>::type; + // make sure the type matches the allowed types + static_assert( + std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + , "incompatible pointer type"); + // delegate the call to get_impl_ptr<>() const return get_impl_ptr(static_cast(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(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 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 +struct DecimalSeparator : std::numpunct { - 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; 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::type>::type>::type; + // make sure the type matches the allowed types + static_assert( + std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + , "incompatible pointer type"); + // delegate the call to get_impl_ptr<>() return get_impl_ptr(static_cast(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::type>::type>::type; + // make sure the type matches the allowed types + static_assert( + std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + or std::is_same::value + , "incompatible pointer type"); + // delegate the call to get_impl_ptr<>() const return get_impl_ptr(static_cast(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(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 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(v)) - : ('a' + static_cast((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 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 c_vector {1, 2, 3, 4}; + json j_vec(c_vector); + // [1, 2, 3, 4] + + std::deque 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 c_list {true, true, false, true}; + json j_list(c_list); + // [true, true, false, true] + + std::forward_list c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543}; + json j_flist(c_flist); + // [12345678909876, 23456789098765, 34567890987654, 45678909876543] + + std::array c_array {{1, 2, 3, 4}}; + json j_array(c_array); + // [1, 2, 3, 4] + + std::set 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 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 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 c_umset {"one", "two", "one", "four"}; + json j_umset(c_umset); // both entries for "one" are used + // maybe ["one", "two", "one", "four"] } - } - { - std::vector c_vector {1, 2, 3, 4}; - json j_vec(c_vector); - // [1, 2, 3, 4] + { + std::map c_map { {"one", 1}, {"two", 2}, {"three", 3} }; + json j_map(c_map); + // {"one": 1, "two": 2, "three": 3} - std::deque 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 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 c_list {true, true, false, true}; - json j_list(c_list); - // [true, true, false, true] + std::multimap 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 c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543}; - json j_flist(c_flist); - // [12345678909876, 23456789098765, 34567890987654, 45678909876543] + std::unordered_multimap 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 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 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 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 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 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(); + bool vb = jb.get(); + int vi = jn.get(); - { - std::map c_map { {"one", 1}, {"two", 2}, {"three", 3} }; - json j_map(c_map); - // {"one": 1, "two": 2, "three": 3} + // etc. + } - std::unordered_map 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 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 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(); - bool vb = jb.get(); - int vi = jn.get(); - - // 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 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 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 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@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html - gsed -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html - gsed -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType >@@g' html/*.html - gsed -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType >@@g' html/*.html + $(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html + $(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html + $(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType >@@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@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html - gsed -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html + $(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html + $(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html make -C html mv html/*.docset . - gsed -i 's@doxygen@json@' me.nlohmann.json.docset/Contents/Info.plist + $(SED) -i 's@doxygen@json@' me.nlohmann.json.docset/Contents/Info.plist rm -fr Doxyfile_docset html From 7f4dd5d6088b7f1cb95acb31d8c4f31503193b64 Mon Sep 17 00:00:00 2001 From: Niels 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 #include #include +#include #include #include #include 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 #include #include +#include #include #include #include From b64367e2f76aa38f6a745e7167fc93fb1c9183fb Mon Sep 17 00:00:00 2001 From: Niels 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 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 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 #include #include -#include #include #include #include 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 #include #include -#include #include #include #include From cb145cfe714769266913a2ff623b9b643984a78f Mon Sep 17 00:00:00 2001 From: Niels 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)