From aee99b362d4be178f84ace541a18e36d7e7b23f4 Mon Sep 17 00:00:00 2001 From: Niels Date: Sun, 24 Jan 2016 19:24:06 +0100 Subject: [PATCH 01/18] some editing --- src/json.hpp | 18 ++++++++++++------ src/json.hpp.re2c | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index 64877d36d..d00d7af66 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -214,13 +214,11 @@ class basic_json /// the type of an element reference using reference = value_type&; - /// the type of an element const reference using const_reference = const value_type&; /// a type to represent differences between iterators using difference_type = std::ptrdiff_t; - /// a type to represent container sizes using size_type = std::size_t; @@ -336,6 +334,14 @@ class basic_json @sa @ref array_t -- type for an array value @since version 1.0.0 + + @note The order name/value pairs are added to the object is *not* preserved + by the library. Therefore, iterating an object may return name/value pairs + in a different order than they were originally stored. In fact, keys will + be traversed in alphabetical order as `std::map` with `std::less` is used + by default. Please note this behavior conforms to [RFC + 7159](http://rfc7159.net/rfc7159), because any order implements the + specified "unordered" nature of JSON objects. */ using object_t = ObjectType Date: Sun, 24 Jan 2016 22:21:27 +0100 Subject: [PATCH 02/18] fixed version number --- src/json.hpp | 6 +++--- src/json.hpp.re2c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index d00d7af66..728b88700 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -2625,7 +2625,7 @@ class basic_json @liveexample{The example shows several calls to `get_ref()`.,get_ref} - @since version 1.0.1 + @since version 1.1.0 */ template reference operator[](T* key) @@ -3204,7 +3204,7 @@ class basic_json with range checking @sa @ref value() for access by value with a default value - @since version 1.0.1 + @since version 1.1.0 */ template const_reference operator[](T* key) const diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 0bf519fd9..e55e1d147 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -2625,7 +2625,7 @@ class basic_json @liveexample{The example shows several calls to `get_ref()`.,get_ref} - @since version 1.0.1 + @since version 1.1.0 */ template reference operator[](T* key) @@ -3204,7 +3204,7 @@ class basic_json with range checking @sa @ref value() for access by value with a default value - @since version 1.0.1 + @since version 1.1.0 */ template const_reference operator[](T* key) const From c09d03fba7b0f47a3622bdde682c3756719794fb Mon Sep 17 00:00:00 2001 From: Niels Date: Sun, 24 Jan 2016 22:43:00 +0100 Subject: [PATCH 03/18] fixed documentation --- doc/Doxyfile | 2 +- doc/examples/basic_json__value_t.output | 2 +- doc/examples/clear.output | 2 +- doc/examples/operator__equal.output | 2 +- doc/examples/operator__notequal.output | 2 +- src/json.hpp | 2 +- src/json.hpp.re2c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/Doxyfile b/doc/Doxyfile index 9cca8a834..a97cb5add 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "JSON for Modern C++" -PROJECT_NUMBER = 1.0.0 +PROJECT_NUMBER = 1.1.0 PROJECT_BRIEF = PROJECT_LOGO = OUTPUT_DIRECTORY = . diff --git a/doc/examples/basic_json__value_t.output b/doc/examples/basic_json__value_t.output index 0a6269fbf..ea542caeb 100644 --- a/doc/examples/basic_json__value_t.output +++ b/doc/examples/basic_json__value_t.output @@ -1,7 +1,7 @@ null false 0 -0 +0.0 {} [] "" diff --git a/doc/examples/clear.output b/doc/examples/clear.output index 0a6269fbf..ea542caeb 100644 --- a/doc/examples/clear.output +++ b/doc/examples/clear.output @@ -1,7 +1,7 @@ null false 0 -0 +0.0 {} [] "" diff --git a/doc/examples/operator__equal.output b/doc/examples/operator__equal.output index e9dfd7551..780673556 100644 --- a/doc/examples/operator__equal.output +++ b/doc/examples/operator__equal.output @@ -1,4 +1,4 @@ [1,2,3] == [1,2,4] false {"A":"a","B":"b"} == {"A":"a","B":"b"} true -17 == 17 true +17 == 17.0 true "foo" == "bar" false diff --git a/doc/examples/operator__notequal.output b/doc/examples/operator__notequal.output index ddd838b4a..9eba626e3 100644 --- a/doc/examples/operator__notequal.output +++ b/doc/examples/operator__notequal.output @@ -1,4 +1,4 @@ [1,2,3] == [1,2,4] true {"A":"a","B":"b"} == {"A":"a","B":"b"} false -17 == 17 false +17 == 17.0 false "foo" == "bar" true diff --git a/src/json.hpp b/src/json.hpp index 728b88700..db7333672 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -32,7 +32,7 @@ Class @ref nlohmann::basic_json is a good entry point for the documentation. @author [Niels Lohmann](http://nlohmann.me) @see https://github.com/nlohmann/json to download the source code -@version 1.0.0 +@version 1.1.0 */ #ifndef NLOHMANN_JSON_HPP diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index e55e1d147..ce2a18f63 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -32,7 +32,7 @@ Class @ref nlohmann::basic_json is a good entry point for the documentation. @author [Niels Lohmann](http://nlohmann.me) @see https://github.com/nlohmann/json to download the source code -@version 1.0.0 +@version 1.1.0 */ #ifndef NLOHMANN_JSON_HPP From 2b137110095c2b2046cde5af4ac8892b8a3f3809 Mon Sep 17 00:00:00 2001 From: Niels Date: Sun, 24 Jan 2016 23:02:28 +0100 Subject: [PATCH 04/18] updated online version --- README.md | 2 +- doc/examples/README.link | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 44c17bf00..721a65918 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![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) [![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json) -[![Try online](https://img.shields.io/badge/try-online-blue.svg)](http://melpon.org/wandbox/permlink/GnGKwji06WeVonlI) +[![Try online](https://img.shields.io/badge/try-online-blue.svg)](http://melpon.org/wandbox/permlink/WSW3gHHE4UcZ9K3G) [![Documentation Status](https://img.shields.io/badge/docs-doxygen-blue.svg)](http://nlohmann.github.io/json) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT) [![Github Releases](https://img.shields.io/github/release/nlohmann/json.svg)](https://github.com/nlohmann/json/releases) diff --git a/doc/examples/README.link b/doc/examples/README.link index 017a2d006..96f5ad8a4 100644 --- a/doc/examples/README.link +++ b/doc/examples/README.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file From a4a88b1b7d1d6db9ff17e09edf6160733e3c485f Mon Sep 17 00:00:00 2001 From: Trevor Welsby Date: Tue, 26 Jan 2016 08:32:15 +1000 Subject: [PATCH 05/18] Issue #195 - update Travis to Trusty due to gcc/clang strtod() bug --- .travis.yml | 7 +- src/json.hpp | 1155 ++++++++++++++++--------------------------------- test/unit.cpp | 4 - 3 files changed, 380 insertions(+), 786 deletions(-) diff --git a/.travis.yml b/.travis.yml index 357c9e593..77bc502de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ language: cpp -sudo: false +dist: trusty +sudo: required # from http://stackoverflow.com/a/32127147/266378 matrix: @@ -33,7 +34,7 @@ matrix: compiler: clang addons: apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.6'] + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-3.6'] packages: ['clang-3.6', 'valgrind'] env: COMPILER=clang++-3.6 @@ -41,7 +42,7 @@ matrix: compiler: clang addons: apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.7'] + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-3.7'] packages: ['clang-3.7', 'valgrind'] env: COMPILER=clang++-3.7 diff --git a/src/json.hpp b/src/json.hpp index db7333672..2fbd1020e 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -6831,789 +6831,386 @@ class basic_json m_start = m_cursor; assert(m_start != nullptr); - - { - lexer_char_t yych; - unsigned int yyaccept = 0; - static const unsigned char yybm[] = - { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 32, 0, 0, 32, 0, 0, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 96, 64, 0, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 0, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - }; - if ((m_limit - m_cursor) < 5) - { - yyfill(); // LCOV_EXCL_LINE; + + { + lexer_char_t yych; + unsigned int yyaccept = 0; + static const unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 32, 0, 0, 32, 0, 0, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 96, 64, 0, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 0, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + }; + if ((m_limit - m_cursor) < 5) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= ':') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x00) goto basic_json_parser_28; + if (yych <= 0x08) goto basic_json_parser_30; + if (yych >= '\n') goto basic_json_parser_4; + } else { + if (yych == '\r') goto basic_json_parser_2; + if (yych <= 0x1F) goto basic_json_parser_30; } - yych = *m_cursor; - if (yych <= ':') - { - if (yych <= ' ') - { - if (yych <= '\n') - { - if (yych <= 0x00) - { - goto basic_json_parser_28; - } - if (yych <= 0x08) - { - goto basic_json_parser_30; - } - if (yych >= '\n') - { - goto basic_json_parser_4; - } - } - else - { - if (yych == '\r') - { - goto basic_json_parser_2; - } - if (yych <= 0x1F) - { - goto basic_json_parser_30; - } - } + } else { + if (yych <= ',') { + if (yych == '"') goto basic_json_parser_27; + if (yych <= '+') goto basic_json_parser_30; + goto basic_json_parser_16; + } else { + if (yych <= '/') { + if (yych <= '-') goto basic_json_parser_23; + goto basic_json_parser_30; + } else { + if (yych <= '0') goto basic_json_parser_24; + if (yych <= '9') goto basic_json_parser_26; + goto basic_json_parser_18; } - else - { - if (yych <= ',') - { - if (yych == '"') - { - goto basic_json_parser_27; - } - if (yych <= '+') - { - goto basic_json_parser_30; - } - goto basic_json_parser_16; - } - else - { - if (yych <= '/') - { - if (yych <= '-') - { - goto basic_json_parser_23; - } - goto basic_json_parser_30; - } - else - { - if (yych <= '0') - { - goto basic_json_parser_24; - } - if (yych <= '9') - { - goto basic_json_parser_26; - } - goto basic_json_parser_18; - } - } - } - } - else - { - if (yych <= 'n') - { - if (yych <= ']') - { - if (yych == '[') - { - goto basic_json_parser_8; - } - if (yych <= '\\') - { - goto basic_json_parser_30; - } - goto basic_json_parser_10; - } - else - { - if (yych == 'f') - { - goto basic_json_parser_22; - } - if (yych <= 'm') - { - goto basic_json_parser_30; - } - goto basic_json_parser_20; - } - } - else - { - if (yych <= '{') - { - if (yych == 't') - { - goto basic_json_parser_21; - } - if (yych <= 'z') - { - goto basic_json_parser_30; - } - goto basic_json_parser_12; - } - else - { - if (yych <= '}') - { - if (yych <= '|') - { - goto basic_json_parser_30; - } - goto basic_json_parser_14; - } - else - { - if (yych == 0xEF) - { - goto basic_json_parser_6; - } - goto basic_json_parser_30; - } - } - } - } -basic_json_parser_2: - ++m_cursor; - yych = *m_cursor; - goto basic_json_parser_5; -basic_json_parser_3: - { - return scan(); - } -basic_json_parser_4: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; -basic_json_parser_5: - if (yybm[0 + yych] & 32) - { - goto basic_json_parser_4; - } - goto basic_json_parser_3; -basic_json_parser_6: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 0xBB) - { - goto basic_json_parser_64; - } -basic_json_parser_7: - { - return token_type::parse_error; - } -basic_json_parser_8: - ++m_cursor; - { - return token_type::begin_array; - } -basic_json_parser_10: - ++m_cursor; - { - return token_type::end_array; - } -basic_json_parser_12: - ++m_cursor; - { - return token_type::begin_object; - } -basic_json_parser_14: - ++m_cursor; - { - return token_type::end_object; - } -basic_json_parser_16: - ++m_cursor; - { - return token_type::value_separator; - } -basic_json_parser_18: - ++m_cursor; - { - return token_type::name_separator; - } -basic_json_parser_20: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'u') - { - goto basic_json_parser_60; - } - goto basic_json_parser_7; -basic_json_parser_21: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'r') - { - goto basic_json_parser_56; - } - goto basic_json_parser_7; -basic_json_parser_22: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'a') - { - goto basic_json_parser_51; - } - goto basic_json_parser_7; -basic_json_parser_23: - yych = *++m_cursor; - if (yych <= '/') - { - goto basic_json_parser_7; - } - if (yych <= '0') - { - goto basic_json_parser_50; - } - if (yych <= '9') - { - goto basic_json_parser_41; - } - goto basic_json_parser_7; -basic_json_parser_24: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - if (yych <= 'D') - { - if (yych == '.') - { - goto basic_json_parser_43; - } - } - else - { - if (yych <= 'E') - { - goto basic_json_parser_44; - } - if (yych == 'e') - { - goto basic_json_parser_44; - } - } -basic_json_parser_25: - { - return token_type::value_number; - } -basic_json_parser_26: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - goto basic_json_parser_42; -basic_json_parser_27: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych <= 0x0F) - { - goto basic_json_parser_7; - } - goto basic_json_parser_32; -basic_json_parser_28: - ++m_cursor; - { - return token_type::end_of_input; - } -basic_json_parser_30: - yych = *++m_cursor; - goto basic_json_parser_7; -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] & 64) - { - goto basic_json_parser_31; - } - if (yych <= 0x0F) - { - goto basic_json_parser_33; - } - if (yych <= '"') - { - goto basic_json_parser_35; - } - goto basic_json_parser_34; -basic_json_parser_33: - m_cursor = m_marker; - if (yyaccept == 0) - { - goto basic_json_parser_7; - } - else - { - goto basic_json_parser_25; - } -basic_json_parser_34: - ++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; - } - goto basic_json_parser_31; - } - else - { - if (yych <= '\\') - { - if (yych <= '[') - { - goto basic_json_parser_33; - } - goto basic_json_parser_31; - } - 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 <= 'r') - { - goto basic_json_parser_31; - } - goto basic_json_parser_33; - } - else - { - if (yych <= 't') - { - goto basic_json_parser_31; - } - if (yych <= 'u') - { - goto basic_json_parser_37; - } - goto basic_json_parser_33; - } - } - } -basic_json_parser_35: - ++m_cursor; - { - return token_type::value_string; - } -basic_json_parser_37: - ++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 >= ':') - { - goto basic_json_parser_33; - } - } - else - { - if (yych <= 'F') - { - goto basic_json_parser_38; - } - if (yych <= '`') - { - goto basic_json_parser_33; - } - if (yych >= 'g') - { - goto basic_json_parser_33; - } - } -basic_json_parser_38: - ++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 >= ':') - { - goto basic_json_parser_33; - } - } - else - { - if (yych <= 'F') - { - goto basic_json_parser_39; - } - if (yych <= '`') - { - goto basic_json_parser_33; - } - if (yych >= 'g') - { - goto basic_json_parser_33; - } - } -basic_json_parser_39: - ++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 >= ':') - { - goto basic_json_parser_33; - } - } - else - { - if (yych <= 'F') - { - goto basic_json_parser_40; - } - if (yych <= '`') - { - goto basic_json_parser_33; - } - if (yych >= 'g') - { - goto basic_json_parser_33; - } - } -basic_json_parser_40: - ++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; - } - 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; - } -basic_json_parser_41: - yyaccept = 1; - m_marker = ++m_cursor; - if ((m_limit - m_cursor) < 3) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; -basic_json_parser_42: - if (yybm[0 + yych] & 128) - { - goto basic_json_parser_41; - } - if (yych <= 'D') - { - if (yych != '.') - { - goto basic_json_parser_25; - } - } - else - { - if (yych <= 'E') - { - goto basic_json_parser_44; - } - if (yych == 'e') - { - goto basic_json_parser_44; - } - goto basic_json_parser_25; - } -basic_json_parser_43: - yych = *++m_cursor; - if (yych <= '/') - { - goto basic_json_parser_33; - } - if (yych <= '9') - { - goto basic_json_parser_48; - } - goto basic_json_parser_33; -basic_json_parser_44: - yych = *++m_cursor; - if (yych <= ',') - { - if (yych != '+') - { - goto basic_json_parser_33; - } - } - else - { - if (yych <= '-') - { - goto basic_json_parser_45; - } - if (yych <= '/') - { - goto basic_json_parser_33; - } - if (yych <= '9') - { - goto basic_json_parser_46; - } - goto basic_json_parser_33; - } -basic_json_parser_45: - yych = *++m_cursor; - if (yych <= '/') - { - goto basic_json_parser_33; - } - if (yych >= ':') - { - goto basic_json_parser_33; - } -basic_json_parser_46: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= '/') - { - goto basic_json_parser_25; - } - if (yych <= '9') - { - goto basic_json_parser_46; - } - goto basic_json_parser_25; -basic_json_parser_48: - 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_25; - } - if (yych <= '9') - { - goto basic_json_parser_48; - } - goto basic_json_parser_25; - } - else - { - if (yych <= 'E') - { - goto basic_json_parser_44; - } - if (yych == 'e') - { - goto basic_json_parser_44; - } - goto basic_json_parser_25; - } -basic_json_parser_50: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - if (yych <= 'D') - { - if (yych == '.') - { - goto basic_json_parser_43; - } - goto basic_json_parser_25; - } - else - { - if (yych <= 'E') - { - goto basic_json_parser_44; - } - if (yych == 'e') - { - goto basic_json_parser_44; - } - goto basic_json_parser_25; - } -basic_json_parser_51: - yych = *++m_cursor; - if (yych != 'l') - { - goto basic_json_parser_33; - } - yych = *++m_cursor; - if (yych != 's') - { - goto basic_json_parser_33; - } - yych = *++m_cursor; - if (yych != 'e') - { - goto basic_json_parser_33; - } - ++m_cursor; - { - return token_type::literal_false; - } -basic_json_parser_56: - yych = *++m_cursor; - if (yych != 'u') - { - goto basic_json_parser_33; - } - yych = *++m_cursor; - if (yych != 'e') - { - goto basic_json_parser_33; - } - ++m_cursor; - { - return token_type::literal_true; - } -basic_json_parser_60: - yych = *++m_cursor; - if (yych != 'l') - { - goto basic_json_parser_33; - } - yych = *++m_cursor; - if (yych != 'l') - { - goto basic_json_parser_33; - } - ++m_cursor; - { - return token_type::literal_null; - } -basic_json_parser_64: - yych = *++m_cursor; - if (yych != 0xBF) - { - goto basic_json_parser_33; - } - ++m_cursor; - { - return scan(); } } + } else { + if (yych <= 'n') { + if (yych <= ']') { + if (yych == '[') goto basic_json_parser_8; + if (yych <= '\\') goto basic_json_parser_30; + goto basic_json_parser_10; + } else { + if (yych == 'f') goto basic_json_parser_22; + if (yych <= 'm') goto basic_json_parser_30; + goto basic_json_parser_20; + } + } else { + if (yych <= '{') { + if (yych == 't') goto basic_json_parser_21; + if (yych <= 'z') goto basic_json_parser_30; + goto basic_json_parser_12; + } else { + if (yych <= '}') { + if (yych <= '|') goto basic_json_parser_30; + goto basic_json_parser_14; + } else { + if (yych == 0xEF) goto basic_json_parser_6; + goto basic_json_parser_30; + } + } + } + } +basic_json_parser_2: + ++m_cursor; + yych = *m_cursor; + goto basic_json_parser_5; +basic_json_parser_3: + { return scan(); } +basic_json_parser_4: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; +basic_json_parser_5: + if (yybm[0+yych] & 32) { + goto basic_json_parser_4; + } + goto basic_json_parser_3; +basic_json_parser_6: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 0xBB) goto basic_json_parser_64; +basic_json_parser_7: + { return token_type::parse_error; } +basic_json_parser_8: + ++m_cursor; + { return token_type::begin_array; } +basic_json_parser_10: + ++m_cursor; + { return token_type::end_array; } +basic_json_parser_12: + ++m_cursor; + { return token_type::begin_object; } +basic_json_parser_14: + ++m_cursor; + { return token_type::end_object; } +basic_json_parser_16: + ++m_cursor; + { return token_type::value_separator; } +basic_json_parser_18: + ++m_cursor; + { return token_type::name_separator; } +basic_json_parser_20: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'u') goto basic_json_parser_60; + goto basic_json_parser_7; +basic_json_parser_21: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'r') goto basic_json_parser_56; + goto basic_json_parser_7; +basic_json_parser_22: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'a') goto basic_json_parser_51; + goto basic_json_parser_7; +basic_json_parser_23: + yych = *++m_cursor; + if (yych <= '/') goto basic_json_parser_7; + if (yych <= '0') goto basic_json_parser_50; + if (yych <= '9') goto basic_json_parser_41; + goto basic_json_parser_7; +basic_json_parser_24: + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + if (yych <= 'D') { + if (yych == '.') goto basic_json_parser_43; + } else { + if (yych <= 'E') goto basic_json_parser_44; + if (yych == 'e') goto basic_json_parser_44; + } +basic_json_parser_25: + { return token_type::value_number; } +basic_json_parser_26: + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + goto basic_json_parser_42; +basic_json_parser_27: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych <= 0x0F) goto basic_json_parser_7; + goto basic_json_parser_32; +basic_json_parser_28: + ++m_cursor; + { return token_type::end_of_input; } +basic_json_parser_30: + yych = *++m_cursor; + goto basic_json_parser_7; +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] & 64) { + goto basic_json_parser_31; + } + if (yych <= 0x0F) goto basic_json_parser_33; + if (yych <= '"') goto basic_json_parser_35; + goto basic_json_parser_34; +basic_json_parser_33: + m_cursor = m_marker; + if (yyaccept == 0) { + goto basic_json_parser_7; + } else { + goto basic_json_parser_25; + } +basic_json_parser_34: + ++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; + goto basic_json_parser_31; + } else { + if (yych <= '\\') { + if (yych <= '[') goto basic_json_parser_33; + goto basic_json_parser_31; + } 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 <= 'r') goto basic_json_parser_31; + goto basic_json_parser_33; + } else { + if (yych <= 't') goto basic_json_parser_31; + if (yych <= 'u') goto basic_json_parser_37; + goto basic_json_parser_33; + } + } + } +basic_json_parser_35: + ++m_cursor; + { return token_type::value_string; } +basic_json_parser_37: + ++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 >= ':') goto basic_json_parser_33; + } else { + if (yych <= 'F') goto basic_json_parser_38; + if (yych <= '`') goto basic_json_parser_33; + if (yych >= 'g') goto basic_json_parser_33; + } +basic_json_parser_38: + ++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 >= ':') goto basic_json_parser_33; + } else { + if (yych <= 'F') goto basic_json_parser_39; + if (yych <= '`') goto basic_json_parser_33; + if (yych >= 'g') goto basic_json_parser_33; + } +basic_json_parser_39: + ++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 >= ':') goto basic_json_parser_33; + } else { + if (yych <= 'F') goto basic_json_parser_40; + if (yych <= '`') goto basic_json_parser_33; + if (yych >= 'g') goto basic_json_parser_33; + } +basic_json_parser_40: + ++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; + } 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; + } +basic_json_parser_41: + yyaccept = 1; + m_marker = ++m_cursor; + if ((m_limit - m_cursor) < 3) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; +basic_json_parser_42: + if (yybm[0+yych] & 128) { + goto basic_json_parser_41; + } + if (yych <= 'D') { + if (yych != '.') goto basic_json_parser_25; + } else { + if (yych <= 'E') goto basic_json_parser_44; + if (yych == 'e') goto basic_json_parser_44; + goto basic_json_parser_25; + } +basic_json_parser_43: + yych = *++m_cursor; + if (yych <= '/') goto basic_json_parser_33; + if (yych <= '9') goto basic_json_parser_48; + goto basic_json_parser_33; +basic_json_parser_44: + yych = *++m_cursor; + if (yych <= ',') { + if (yych != '+') goto basic_json_parser_33; + } else { + if (yych <= '-') goto basic_json_parser_45; + if (yych <= '/') goto basic_json_parser_33; + if (yych <= '9') goto basic_json_parser_46; + goto basic_json_parser_33; + } +basic_json_parser_45: + yych = *++m_cursor; + if (yych <= '/') goto basic_json_parser_33; + if (yych >= ':') goto basic_json_parser_33; +basic_json_parser_46: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= '/') goto basic_json_parser_25; + if (yych <= '9') goto basic_json_parser_46; + goto basic_json_parser_25; +basic_json_parser_48: + 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_25; + if (yych <= '9') goto basic_json_parser_48; + goto basic_json_parser_25; + } else { + if (yych <= 'E') goto basic_json_parser_44; + if (yych == 'e') goto basic_json_parser_44; + goto basic_json_parser_25; + } +basic_json_parser_50: + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + if (yych <= 'D') { + if (yych == '.') goto basic_json_parser_43; + goto basic_json_parser_25; + } else { + if (yych <= 'E') goto basic_json_parser_44; + if (yych == 'e') goto basic_json_parser_44; + goto basic_json_parser_25; + } +basic_json_parser_51: + yych = *++m_cursor; + if (yych != 'l') goto basic_json_parser_33; + yych = *++m_cursor; + if (yych != 's') goto basic_json_parser_33; + yych = *++m_cursor; + if (yych != 'e') goto basic_json_parser_33; + ++m_cursor; + { return token_type::literal_false; } +basic_json_parser_56: + yych = *++m_cursor; + if (yych != 'u') goto basic_json_parser_33; + yych = *++m_cursor; + if (yych != 'e') goto basic_json_parser_33; + ++m_cursor; + { return token_type::literal_true; } +basic_json_parser_60: + yych = *++m_cursor; + if (yych != 'l') goto basic_json_parser_33; + yych = *++m_cursor; + if (yych != 'l') goto basic_json_parser_33; + ++m_cursor; + { return token_type::literal_null; } +basic_json_parser_64: + yych = *++m_cursor; + if (yych != 0xBF) goto basic_json_parser_33; + ++m_cursor; + { return scan(); } + } } diff --git a/test/unit.cpp b/test/unit.cpp index d800398e9..46d52ad54 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -11572,12 +11572,8 @@ TEST_CASE("regression tests") j = json::parse("0.999999999999999944488848768742172978818416595458984374"); CHECK(j.get() == 0.99999999999999989); - // Test fails under GCC/clang due to strtod() error (may originate in libstdc++ - // but seems to have been fixed in the most current versions - just not on Travis) -#if !defined(__clang__) && !defined(__GNUC__) && !defined(__GNUG__) j = json::parse("1.00000000000000011102230246251565404236316680908203126"); CHECK(j.get() == 1.00000000000000022); -#endif j = json::parse("7205759403792793199999e-5"); CHECK(j.get() == 72057594037927928.0); From 2de94365dec517bfc0940aecf315a2c90a664d84 Mon Sep 17 00:00:00 2001 From: Trevor Welsby Date: Tue, 26 Jan 2016 09:14:43 +1000 Subject: [PATCH 06/18] Revert to llvm-toolchain-precise-* due to Travis white-list issue --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 77bc502de..2b75fc436 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ matrix: compiler: clang addons: apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-3.6'] + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.6'] packages: ['clang-3.6', 'valgrind'] env: COMPILER=clang++-3.6 @@ -42,7 +42,7 @@ matrix: compiler: clang addons: apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-3.7'] + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.7'] packages: ['clang-3.7', 'valgrind'] env: COMPILER=clang++-3.7 From 08fd6dbf98e92889051ca3695752f71380e5f795 Mon Sep 17 00:00:00 2001 From: Volker Diels-Grabsch Date: Tue, 26 Jan 2016 15:22:15 +0100 Subject: [PATCH 07/18] Fix broken link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 721a65918..cbb4c0140 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Other aspects were not so important to us: - **Speed**. We currently implement the parser as naive [recursive descent parser](http://en.wikipedia.org/wiki/Recursive_descent_parser) with hand coded string handling. It is fast enough, but a [LALR-parser](http://en.wikipedia.org/wiki/LALR_parser) with a decent regular expression processor should be even faster (but would consist of more files which makes the integration harder). -See the [https://github.com/nlohmann/json/blob/master/CONTRIBUTING.md#please-dont](contribution guidelines) for more information. +See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/CONTRIBUTING.md#please-dont) for more information. ## Integration From b630ce0e78e16276d7bfd5e29e27f7321c90edfc Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 26 Jan 2016 19:11:58 +0100 Subject: [PATCH 08/18] thanks --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cbb4c0140..371b93246 100644 --- a/README.md +++ b/README.md @@ -391,6 +391,7 @@ I deeply appreciate the help of the following people. - [Glen Fernandes](https://github.com/glenfe) noted a potential portability problem in the `has_mapped_type` function. - [Corbin Hughes](https://github.com/nibroc) fixed some typos in the contribution guidelines. - [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. +- [Volker Diels-Grabsch](https://github.com/vog) fixed a link in the README file. Thanks a lot for helping out! From 11ae1d0f0969e47019dcd96b3b0ddcbbfb72af30 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 26 Jan 2016 19:13:03 +0100 Subject: [PATCH 09/18] cleanup after #196 --- src/json.hpp | 1063 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 733 insertions(+), 330 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index 2fbd1020e..db7333672 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -6831,386 +6831,789 @@ class basic_json m_start = m_cursor; assert(m_start != nullptr); - - { - lexer_char_t yych; - unsigned int yyaccept = 0; - static const unsigned char yybm[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 32, 0, 0, 32, 0, 0, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 96, 64, 0, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 0, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - }; - if ((m_limit - m_cursor) < 5) yyfill(); // LCOV_EXCL_LINE; - yych = *m_cursor; - if (yych <= ':') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x00) goto basic_json_parser_28; - if (yych <= 0x08) goto basic_json_parser_30; - if (yych >= '\n') goto basic_json_parser_4; - } else { - if (yych == '\r') goto basic_json_parser_2; - if (yych <= 0x1F) goto basic_json_parser_30; + + { + lexer_char_t yych; + unsigned int yyaccept = 0; + static const unsigned char yybm[] = + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 32, 0, 0, 32, 0, 0, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 96, 64, 0, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 0, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + }; + if ((m_limit - m_cursor) < 5) + { + yyfill(); // LCOV_EXCL_LINE; } - } else { - if (yych <= ',') { - if (yych == '"') goto basic_json_parser_27; - if (yych <= '+') goto basic_json_parser_30; - goto basic_json_parser_16; - } else { - if (yych <= '/') { - if (yych <= '-') goto basic_json_parser_23; - goto basic_json_parser_30; - } else { - if (yych <= '0') goto basic_json_parser_24; - if (yych <= '9') goto basic_json_parser_26; - goto basic_json_parser_18; + yych = *m_cursor; + if (yych <= ':') + { + if (yych <= ' ') + { + if (yych <= '\n') + { + if (yych <= 0x00) + { + goto basic_json_parser_28; + } + if (yych <= 0x08) + { + goto basic_json_parser_30; + } + if (yych >= '\n') + { + goto basic_json_parser_4; + } + } + else + { + if (yych == '\r') + { + goto basic_json_parser_2; + } + if (yych <= 0x1F) + { + goto basic_json_parser_30; + } + } + } + else + { + if (yych <= ',') + { + if (yych == '"') + { + goto basic_json_parser_27; + } + if (yych <= '+') + { + goto basic_json_parser_30; + } + goto basic_json_parser_16; + } + else + { + if (yych <= '/') + { + if (yych <= '-') + { + goto basic_json_parser_23; + } + goto basic_json_parser_30; + } + else + { + if (yych <= '0') + { + goto basic_json_parser_24; + } + if (yych <= '9') + { + goto basic_json_parser_26; + } + goto basic_json_parser_18; + } + } } } - } - } else { - if (yych <= 'n') { - if (yych <= ']') { - if (yych == '[') goto basic_json_parser_8; - if (yych <= '\\') goto basic_json_parser_30; - goto basic_json_parser_10; - } else { - if (yych == 'f') goto basic_json_parser_22; - if (yych <= 'm') goto basic_json_parser_30; - goto basic_json_parser_20; - } - } else { - if (yych <= '{') { - if (yych == 't') goto basic_json_parser_21; - if (yych <= 'z') goto basic_json_parser_30; - goto basic_json_parser_12; - } else { - if (yych <= '}') { - if (yych <= '|') goto basic_json_parser_30; - goto basic_json_parser_14; - } else { - if (yych == 0xEF) goto basic_json_parser_6; - goto basic_json_parser_30; + else + { + if (yych <= 'n') + { + if (yych <= ']') + { + if (yych == '[') + { + goto basic_json_parser_8; + } + if (yych <= '\\') + { + goto basic_json_parser_30; + } + goto basic_json_parser_10; + } + else + { + if (yych == 'f') + { + goto basic_json_parser_22; + } + if (yych <= 'm') + { + goto basic_json_parser_30; + } + goto basic_json_parser_20; + } + } + else + { + if (yych <= '{') + { + if (yych == 't') + { + goto basic_json_parser_21; + } + if (yych <= 'z') + { + goto basic_json_parser_30; + } + goto basic_json_parser_12; + } + else + { + if (yych <= '}') + { + if (yych <= '|') + { + goto basic_json_parser_30; + } + goto basic_json_parser_14; + } + else + { + if (yych == 0xEF) + { + goto basic_json_parser_6; + } + goto basic_json_parser_30; + } + } } } - } - } basic_json_parser_2: - ++m_cursor; - yych = *m_cursor; - goto basic_json_parser_5; + ++m_cursor; + yych = *m_cursor; + goto basic_json_parser_5; basic_json_parser_3: - { return scan(); } + { + return scan(); + } basic_json_parser_4: - ++m_cursor; - if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; - yych = *m_cursor; + ++m_cursor; + if (m_limit <= m_cursor) + { + yyfill(); // LCOV_EXCL_LINE; + } + yych = *m_cursor; basic_json_parser_5: - if (yybm[0+yych] & 32) { - goto basic_json_parser_4; - } - goto basic_json_parser_3; + if (yybm[0 + yych] & 32) + { + goto basic_json_parser_4; + } + goto basic_json_parser_3; basic_json_parser_6: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 0xBB) goto basic_json_parser_64; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 0xBB) + { + goto basic_json_parser_64; + } basic_json_parser_7: - { return token_type::parse_error; } + { + return token_type::parse_error; + } basic_json_parser_8: - ++m_cursor; - { return token_type::begin_array; } + ++m_cursor; + { + return token_type::begin_array; + } basic_json_parser_10: - ++m_cursor; - { return token_type::end_array; } + ++m_cursor; + { + return token_type::end_array; + } basic_json_parser_12: - ++m_cursor; - { return token_type::begin_object; } + ++m_cursor; + { + return token_type::begin_object; + } basic_json_parser_14: - ++m_cursor; - { return token_type::end_object; } + ++m_cursor; + { + return token_type::end_object; + } basic_json_parser_16: - ++m_cursor; - { return token_type::value_separator; } + ++m_cursor; + { + return token_type::value_separator; + } basic_json_parser_18: - ++m_cursor; - { return token_type::name_separator; } + ++m_cursor; + { + return token_type::name_separator; + } basic_json_parser_20: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'u') goto basic_json_parser_60; - goto basic_json_parser_7; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'u') + { + goto basic_json_parser_60; + } + goto basic_json_parser_7; basic_json_parser_21: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'r') goto basic_json_parser_56; - goto basic_json_parser_7; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'r') + { + goto basic_json_parser_56; + } + goto basic_json_parser_7; basic_json_parser_22: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'a') goto basic_json_parser_51; - goto basic_json_parser_7; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'a') + { + goto basic_json_parser_51; + } + goto basic_json_parser_7; basic_json_parser_23: - yych = *++m_cursor; - if (yych <= '/') goto basic_json_parser_7; - if (yych <= '0') goto basic_json_parser_50; - if (yych <= '9') goto basic_json_parser_41; - goto basic_json_parser_7; + yych = *++m_cursor; + if (yych <= '/') + { + goto basic_json_parser_7; + } + if (yych <= '0') + { + goto basic_json_parser_50; + } + if (yych <= '9') + { + goto basic_json_parser_41; + } + goto basic_json_parser_7; basic_json_parser_24: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - if (yych <= 'D') { - if (yych == '.') goto basic_json_parser_43; - } else { - if (yych <= 'E') goto basic_json_parser_44; - if (yych == 'e') goto basic_json_parser_44; - } + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + if (yych <= 'D') + { + if (yych == '.') + { + goto basic_json_parser_43; + } + } + else + { + if (yych <= 'E') + { + goto basic_json_parser_44; + } + if (yych == 'e') + { + goto basic_json_parser_44; + } + } basic_json_parser_25: - { return token_type::value_number; } + { + return token_type::value_number; + } basic_json_parser_26: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - goto basic_json_parser_42; + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + goto basic_json_parser_42; basic_json_parser_27: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych <= 0x0F) goto basic_json_parser_7; - goto basic_json_parser_32; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych <= 0x0F) + { + goto basic_json_parser_7; + } + goto basic_json_parser_32; basic_json_parser_28: - ++m_cursor; - { return token_type::end_of_input; } + ++m_cursor; + { + return token_type::end_of_input; + } basic_json_parser_30: - yych = *++m_cursor; - goto basic_json_parser_7; + yych = *++m_cursor; + goto basic_json_parser_7; basic_json_parser_31: - ++m_cursor; - if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; - yych = *m_cursor; + ++m_cursor; + if (m_limit <= m_cursor) + { + yyfill(); // LCOV_EXCL_LINE; + } + yych = *m_cursor; basic_json_parser_32: - if (yybm[0+yych] & 64) { - goto basic_json_parser_31; - } - if (yych <= 0x0F) goto basic_json_parser_33; - if (yych <= '"') goto basic_json_parser_35; - goto basic_json_parser_34; -basic_json_parser_33: - m_cursor = m_marker; - if (yyaccept == 0) { - goto basic_json_parser_7; - } else { - goto basic_json_parser_25; - } -basic_json_parser_34: - ++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; - goto basic_json_parser_31; - } else { - if (yych <= '\\') { - if (yych <= '[') goto basic_json_parser_33; + if (yybm[0 + yych] & 64) + { goto basic_json_parser_31; - } else { - if (yych == 'b') goto basic_json_parser_31; + } + if (yych <= 0x0F) + { 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 <= 'r') goto basic_json_parser_31; - goto basic_json_parser_33; - } else { - if (yych <= 't') goto basic_json_parser_31; - if (yych <= 'u') goto basic_json_parser_37; - goto basic_json_parser_33; + if (yych <= '"') + { + goto basic_json_parser_35; + } + goto basic_json_parser_34; +basic_json_parser_33: + m_cursor = m_marker; + if (yyaccept == 0) + { + goto basic_json_parser_7; + } + else + { + goto basic_json_parser_25; + } +basic_json_parser_34: + ++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; + } + goto basic_json_parser_31; + } + else + { + if (yych <= '\\') + { + if (yych <= '[') + { + goto basic_json_parser_33; + } + goto basic_json_parser_31; + } + 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 <= 'r') + { + goto basic_json_parser_31; + } + goto basic_json_parser_33; + } + else + { + if (yych <= 't') + { + goto basic_json_parser_31; + } + if (yych <= 'u') + { + goto basic_json_parser_37; + } + goto basic_json_parser_33; + } + } } - } - } basic_json_parser_35: - ++m_cursor; - { return token_type::value_string; } + ++m_cursor; + { + return token_type::value_string; + } basic_json_parser_37: - ++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 >= ':') goto basic_json_parser_33; - } else { - if (yych <= 'F') goto basic_json_parser_38; - if (yych <= '`') goto basic_json_parser_33; - if (yych >= 'g') goto basic_json_parser_33; - } + ++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 >= ':') + { + goto basic_json_parser_33; + } + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_38; + } + if (yych <= '`') + { + goto basic_json_parser_33; + } + if (yych >= 'g') + { + goto basic_json_parser_33; + } + } basic_json_parser_38: - ++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 >= ':') goto basic_json_parser_33; - } else { - if (yych <= 'F') goto basic_json_parser_39; - if (yych <= '`') goto basic_json_parser_33; - if (yych >= 'g') goto basic_json_parser_33; - } + ++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 >= ':') + { + goto basic_json_parser_33; + } + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_39; + } + if (yych <= '`') + { + goto basic_json_parser_33; + } + if (yych >= 'g') + { + goto basic_json_parser_33; + } + } basic_json_parser_39: - ++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 >= ':') goto basic_json_parser_33; - } else { - if (yych <= 'F') goto basic_json_parser_40; - if (yych <= '`') goto basic_json_parser_33; - if (yych >= 'g') goto basic_json_parser_33; - } + ++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 >= ':') + { + goto basic_json_parser_33; + } + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_40; + } + if (yych <= '`') + { + goto basic_json_parser_33; + } + if (yych >= 'g') + { + goto basic_json_parser_33; + } + } basic_json_parser_40: - ++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; - } 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; - } + ++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; + } + 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; + } basic_json_parser_41: - yyaccept = 1; - m_marker = ++m_cursor; - if ((m_limit - m_cursor) < 3) yyfill(); // LCOV_EXCL_LINE; - yych = *m_cursor; + yyaccept = 1; + m_marker = ++m_cursor; + if ((m_limit - m_cursor) < 3) + { + yyfill(); // LCOV_EXCL_LINE; + } + yych = *m_cursor; basic_json_parser_42: - if (yybm[0+yych] & 128) { - goto basic_json_parser_41; - } - if (yych <= 'D') { - if (yych != '.') goto basic_json_parser_25; - } else { - if (yych <= 'E') goto basic_json_parser_44; - if (yych == 'e') goto basic_json_parser_44; - goto basic_json_parser_25; - } + if (yybm[0 + yych] & 128) + { + goto basic_json_parser_41; + } + if (yych <= 'D') + { + if (yych != '.') + { + goto basic_json_parser_25; + } + } + else + { + if (yych <= 'E') + { + goto basic_json_parser_44; + } + if (yych == 'e') + { + goto basic_json_parser_44; + } + goto basic_json_parser_25; + } basic_json_parser_43: - yych = *++m_cursor; - if (yych <= '/') goto basic_json_parser_33; - if (yych <= '9') goto basic_json_parser_48; - goto basic_json_parser_33; + yych = *++m_cursor; + if (yych <= '/') + { + goto basic_json_parser_33; + } + if (yych <= '9') + { + goto basic_json_parser_48; + } + goto basic_json_parser_33; basic_json_parser_44: - yych = *++m_cursor; - if (yych <= ',') { - if (yych != '+') goto basic_json_parser_33; - } else { - if (yych <= '-') goto basic_json_parser_45; - if (yych <= '/') goto basic_json_parser_33; - if (yych <= '9') goto basic_json_parser_46; - goto basic_json_parser_33; - } + yych = *++m_cursor; + if (yych <= ',') + { + if (yych != '+') + { + goto basic_json_parser_33; + } + } + else + { + if (yych <= '-') + { + goto basic_json_parser_45; + } + if (yych <= '/') + { + goto basic_json_parser_33; + } + if (yych <= '9') + { + goto basic_json_parser_46; + } + goto basic_json_parser_33; + } basic_json_parser_45: - yych = *++m_cursor; - if (yych <= '/') goto basic_json_parser_33; - if (yych >= ':') goto basic_json_parser_33; + yych = *++m_cursor; + if (yych <= '/') + { + goto basic_json_parser_33; + } + if (yych >= ':') + { + goto basic_json_parser_33; + } basic_json_parser_46: - ++m_cursor; - if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; - yych = *m_cursor; - if (yych <= '/') goto basic_json_parser_25; - if (yych <= '9') goto basic_json_parser_46; - goto basic_json_parser_25; + ++m_cursor; + if (m_limit <= m_cursor) + { + yyfill(); // LCOV_EXCL_LINE; + } + yych = *m_cursor; + if (yych <= '/') + { + goto basic_json_parser_25; + } + if (yych <= '9') + { + goto basic_json_parser_46; + } + goto basic_json_parser_25; basic_json_parser_48: - 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_25; - if (yych <= '9') goto basic_json_parser_48; - goto basic_json_parser_25; - } else { - if (yych <= 'E') goto basic_json_parser_44; - if (yych == 'e') goto basic_json_parser_44; - goto basic_json_parser_25; - } + 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_25; + } + if (yych <= '9') + { + goto basic_json_parser_48; + } + goto basic_json_parser_25; + } + else + { + if (yych <= 'E') + { + goto basic_json_parser_44; + } + if (yych == 'e') + { + goto basic_json_parser_44; + } + goto basic_json_parser_25; + } basic_json_parser_50: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - if (yych <= 'D') { - if (yych == '.') goto basic_json_parser_43; - goto basic_json_parser_25; - } else { - if (yych <= 'E') goto basic_json_parser_44; - if (yych == 'e') goto basic_json_parser_44; - goto basic_json_parser_25; - } + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + if (yych <= 'D') + { + if (yych == '.') + { + goto basic_json_parser_43; + } + goto basic_json_parser_25; + } + else + { + if (yych <= 'E') + { + goto basic_json_parser_44; + } + if (yych == 'e') + { + goto basic_json_parser_44; + } + goto basic_json_parser_25; + } basic_json_parser_51: - yych = *++m_cursor; - if (yych != 'l') goto basic_json_parser_33; - yych = *++m_cursor; - if (yych != 's') goto basic_json_parser_33; - yych = *++m_cursor; - if (yych != 'e') goto basic_json_parser_33; - ++m_cursor; - { return token_type::literal_false; } + yych = *++m_cursor; + if (yych != 'l') + { + goto basic_json_parser_33; + } + yych = *++m_cursor; + if (yych != 's') + { + goto basic_json_parser_33; + } + yych = *++m_cursor; + if (yych != 'e') + { + goto basic_json_parser_33; + } + ++m_cursor; + { + return token_type::literal_false; + } basic_json_parser_56: - yych = *++m_cursor; - if (yych != 'u') goto basic_json_parser_33; - yych = *++m_cursor; - if (yych != 'e') goto basic_json_parser_33; - ++m_cursor; - { return token_type::literal_true; } + yych = *++m_cursor; + if (yych != 'u') + { + goto basic_json_parser_33; + } + yych = *++m_cursor; + if (yych != 'e') + { + goto basic_json_parser_33; + } + ++m_cursor; + { + return token_type::literal_true; + } basic_json_parser_60: - yych = *++m_cursor; - if (yych != 'l') goto basic_json_parser_33; - yych = *++m_cursor; - if (yych != 'l') goto basic_json_parser_33; - ++m_cursor; - { return token_type::literal_null; } + yych = *++m_cursor; + if (yych != 'l') + { + goto basic_json_parser_33; + } + yych = *++m_cursor; + if (yych != 'l') + { + goto basic_json_parser_33; + } + ++m_cursor; + { + return token_type::literal_null; + } basic_json_parser_64: - yych = *++m_cursor; - if (yych != 0xBF) goto basic_json_parser_33; - ++m_cursor; - { return scan(); } - } + yych = *++m_cursor; + if (yych != 0xBF) + { + goto basic_json_parser_33; + } + ++m_cursor; + { + return scan(); + } + } } From d338042e3ea08b915e9f8096ea4334c9c9e21dbb Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 26 Jan 2016 19:21:46 +0100 Subject: [PATCH 10/18] added note to warn about floating-point exceptions (#181) --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 371b93246..acb2e9e2b 100644 --- a/README.md +++ b/README.md @@ -397,7 +397,8 @@ Thanks a lot for helping out! ## Notes -- The code contains numerous debug assertions which can be switched off by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](http://en.cppreference.com/w/cpp/error/assert). +- The code contains numerous debug **assertions** which can be switched off by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](http://en.cppreference.com/w/cpp/error/assert). +- As the exact type of a number is not defined in the [JSON specification](http://rfc7159.net/rfc7159), this library tries to choose the best fitting C++ number type automatically. As a result, the type `double` may be used to store numbers which may yield [**floating-point exceptions**](https://github.com/nlohmann/json/issues/181) in certain rare situations if floating-point exceptions have been unmasked in the calling code. These exceptions are not caused by the library and need to be fixed in the calling code, such as by re-masking the exceptions prior to calling library functions. ## Execute unit tests From 707732a53ebf5efc8555413180896e13fdd5ec04 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 26 Jan 2016 19:50:49 +0100 Subject: [PATCH 11/18] clean up after #193 --- README.md | 4 +- src/json.hpp | 1287 ++++++++++++++++++++++++++++++--------------- src/json.hpp.re2c | 224 ++++---- test/unit.cpp | 42 +- 4 files changed, 1012 insertions(+), 545 deletions(-) diff --git a/README.md b/README.md index acb2e9e2b..8d180c282 100644 --- a/README.md +++ b/README.md @@ -390,7 +390,7 @@ I deeply appreciate the help of the following people. - [406345](https://github.com/406345) fixed two small warnings. - [Glen Fernandes](https://github.com/glenfe) noted a potential portability problem in the `has_mapped_type` function. - [Corbin Hughes](https://github.com/nibroc) fixed some typos in the contribution guidelines. -- [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. +- [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. He further added support for unsigned integer numbers. - [Volker Diels-Grabsch](https://github.com/vog) fixed a link in the README file. Thanks a lot for helping out! @@ -409,7 +409,7 @@ $ make $ ./json_unit "*" =============================================================================== -All tests passed (3343329 assertions in 29 test cases) +All tests passed (3344278 assertions in 29 test cases) ``` For more information, have a look at the file [.travis.yml](https://github.com/nlohmann/json/blob/master/.travis.yml). diff --git a/src/json.hpp b/src/json.hpp index 3bba54a64..8b8ed337b 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -124,8 +124,8 @@ default; will be used in @ref string_t) in @ref boolean_t) @tparam NumberIntegerType type for JSON integer numbers (@c `int64_t` by default; will be used in @ref number_integer_t) -@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c `uint64_t` by -default; will be used in @ref number_unsigned_t) +@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c +`uint64_t` by default; will be used in @ref number_unsigned_t) @tparam NumberFloatType type for JSON floating-point numbers (@c `double` by default; will be used in @ref number_float_t) @tparam AllocatorType type of the allocator to use (@c `std::allocator` by @@ -485,9 +485,9 @@ class basic_json > permitted. This description includes both integer and floating-point numbers. However, - C++ allows more precise storage if it is known whether the number is a + C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, - three different types, @ref number_integer_t, @ref number_unsigned_t and + three different types, @ref number_integer_t, @ref number_unsigned_t and @ref number_float_t are used. To store integer numbers in C++, a type is defined by the template @@ -556,9 +556,9 @@ class basic_json > permitted. This description includes both integer and floating-point numbers. However, - C++ allows more precise storage if it is known whether the number is a + C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, - three different types, @ref number_integer_t, @ref number_unsigned_t and + three different types, @ref number_integer_t, @ref number_unsigned_t and @ref number_float_t are used. To store unsigned integer numbers in C++, a type is defined by the template @@ -588,11 +588,11 @@ class basic_json > An implementation may set limits on the range and precision of numbers. When the default type is used, the maximal integer number that can be - stored is `18446744073709551615` (UINT64_MAX) and the minimal integer number - that can be stored is `0`. Integer numbers - that are out of range will yield over/underflow when used in a constructor. - During deserialization, too large or small integer numbers will be - automatically be stored as @ref number_integer_t or @ref number_float_t. + stored is `18446744073709551615` (UINT64_MAX) and the minimal integer + number that can be stored is `0`. Integer numbers that are out of range + will yield over/underflow when used in a constructor. During + deserialization, too large or small integer numbers will be automatically + be stored as @ref number_integer_t or @ref number_float_t. [RFC 7159](http://rfc7159.net/rfc7159) further states: > Note that when such software is used, numbers that are integers and are @@ -600,7 +600,7 @@ class basic_json > that implementations will agree exactly on their numeric values. As this range is a subrange (when considered in conjunction with the - number_integer_t type) of the exactly supported range [0, UINT64_MAX], this + number_integer_t type) of the exactly supported range [0, UINT64_MAX], this class's integer type is interoperable. #### Storage @@ -614,7 +614,7 @@ class basic_json @since version 2.0.0 */ using number_unsigned_t = NumberUnsignedType; - + /*! @brief a type for a number (floating-point) @@ -628,9 +628,9 @@ class basic_json > permitted. This description includes both integer and floating-point numbers. However, - C++ allows more precise storage if it is known whether the number is a + C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, - three different types, @ref number_integer_t, @ref number_unsigned_t and + three different types, @ref number_integer_t, @ref number_unsigned_t and @ref number_float_t are used. To store floating-point numbers in C++, a type is defined by the template @@ -801,7 +801,7 @@ class basic_json number_integer = number_integer_t(0); break; } - + case value_t::number_unsigned: { number_unsigned = number_unsigned_t(0); @@ -1330,8 +1330,8 @@ class basic_json template::value and - std::numeric_limits::is_integer and - std::numeric_limits::is_signed, + std::numeric_limits::is_integer and + std::numeric_limits::is_signed, CompatibleNumberIntegerType>::type = 0> basic_json(const CompatibleNumberIntegerType val) noexcept @@ -1344,7 +1344,7 @@ class basic_json Create an unsigned integer number JSON value with a given content. - @tparam T helper type to compare number_unsigned_t and unsigned int + @tparam T helper type to compare number_unsigned_t and unsigned int (not visible in) the interface. @param[in] val an integer to create a JSON number from @@ -1365,14 +1365,14 @@ class basic_json basic_json(const number_unsigned_t val) : m_type(value_t::number_unsigned), m_value(val) {} - + /*! @brief create an unsigned number (implicit) Create an unsigned number JSON value with a given content. This constructor allows any type that can be used to construct values of type @ref - number_unsigned_t. Examples may include the types `unsigned int`, `uint32_t`, - or `unsigned short`. + number_unsigned_t. Examples may include the types `unsigned int`, + `uint32_t`, or `unsigned short`. @tparam CompatibleNumberUnsignedType an integer type which is compatible to @ref number_unsigned_t. @@ -1386,13 +1386,13 @@ class basic_json @since version 2.0.0 */ - template::value and - std::numeric_limits::is_integer and - !std::numeric_limits::is_signed, - CompatibleNumberUnsignedType>::type - = 0> + template < typename CompatibleNumberUnsignedType, typename + std::enable_if < + std::is_constructible::value and + std::numeric_limits::is_integer and + !std::numeric_limits::is_signed, + CompatibleNumberUnsignedType >::type + = 0 > basic_json(const CompatibleNumberUnsignedType val) noexcept : m_type(value_t::number_unsigned), m_value(static_cast(val)) @@ -1781,7 +1781,7 @@ class basic_json m_value.number_integer = first.m_object->m_value.number_integer; break; } - + case value_t::number_unsigned: { assert(first.m_object != nullptr); @@ -1891,7 +1891,7 @@ class basic_json m_value = other.m_value.number_integer; break; } - + case value_t::number_unsigned: { m_value = other.m_value.number_unsigned; @@ -2183,9 +2183,10 @@ class basic_json @liveexample{The following code exemplifies @ref is_number for all JSON types.,is_number} - @sa @ref is_number_integer() -- check if value is an integer or unsigned + @sa @ref is_number_integer() -- check if value is an integer or unsigned integer number - @sa @ref is_number_unsigned() -- check if value is an unsigned integer number + @sa @ref is_number_unsigned() -- check if value is an unsigned integer + number @sa @ref is_number_float() -- check if value is a floating-point number @since version 1.0.0 @@ -2198,10 +2199,10 @@ class basic_json /*! @brief return whether value is an integer number - This function returns true iff the JSON value is an integer or unsigned + This function returns true iff the JSON value is an integer or unsigned integer number. This excludes floating-point values. - @return `true` if type is an integer or unsigned integer number, `false` + @return `true` if type is an integer or unsigned integer number, `false` otherwise. @complexity Constant. @@ -2210,7 +2211,8 @@ class basic_json JSON types.,is_number_integer} @sa @ref is_number() -- check if value is a number - @sa @ref is_number_unsigned() -- check if value is an unsigned integer number + @sa @ref is_number_unsigned() -- check if value is an unsigned integer + number @sa @ref is_number_float() -- check if value is a floating-point number @since version 1.0.0 @@ -2219,19 +2221,19 @@ class basic_json { return m_type == value_t::number_integer or m_type == value_t::number_unsigned; } - + /*! @brief return whether value is an unsigned integer number - This function returns true iff the JSON value is an unsigned integer number. - This excludes floating-point and (signed) integer values. + This function returns true iff the JSON value is an unsigned integer + number. This excludes floating-point and (signed) integer values. @return `true` if type is an unsigned integer number, `false` otherwise. @complexity Constant. @sa @ref is_number() -- check if value is a number - @sa @ref is_number_integer() -- check if value is an integer or unsigned + @sa @ref is_number_integer() -- check if value is an integer or unsigned integer number @sa @ref is_number_float() -- check if value is a floating-point number @@ -2257,7 +2259,8 @@ class basic_json @sa @ref is_number() -- check if value is number @sa @ref is_number_integer() -- check if value is an integer number - @sa @ref is_number_unsigned() -- check if value is an unsigned integer number + @sa @ref is_number_unsigned() -- check if value is an unsigned integer + number @since version 1.0.0 */ @@ -2525,7 +2528,7 @@ class basic_json { return static_cast(m_value.number_integer); } - + case value_t::number_unsigned: { return static_cast(m_value.number_unsigned); @@ -2615,7 +2618,7 @@ class basic_json { return is_number_integer() ? &m_value.number_integer : nullptr; } - + /// get a pointer to the value (unsigned number) number_unsigned_t* get_impl_ptr(number_unsigned_t*) noexcept { @@ -2627,7 +2630,7 @@ class basic_json { return is_number_unsigned() ? &m_value.number_unsigned : nullptr; } - + /// get a pointer to the value (floating-point number) number_float_t* get_impl_ptr(number_float_t*) noexcept { @@ -2725,7 +2728,7 @@ class basic_json @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, + object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, @ref number_unsigned_t, or @ref number_float_t. @return pointer to the internally stored JSON value if the requested @@ -2776,7 +2779,7 @@ class basic_json state. @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, + object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, @ref number_unsigned_t, or @ref number_float_t. @return pointer to the internally stored JSON value if the requested @@ -2895,14 +2898,14 @@ class basic_json @since version 1.0.0 */ - template::value - and not std::is_same::value + template < typename ValueType, typename + std::enable_if < + not std::is_pointer::value + and not std::is_same::value #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 - and not std::is_same>::value + and not std::is_same>::value #endif - , int>::type = 0> + , int >::type = 0 > operator ValueType() const { // delegate the call to get<>() const @@ -7100,386 +7103,789 @@ class basic_json m_start = m_cursor; assert(m_start != nullptr); - - { - lexer_char_t yych; - unsigned int yyaccept = 0; - static const unsigned char yybm[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 32, 0, 0, 32, 0, 0, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 96, 64, 0, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 0, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - }; - if ((m_limit - m_cursor) < 5) yyfill(); // LCOV_EXCL_LINE; - yych = *m_cursor; - if (yych <= ':') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x00) goto basic_json_parser_28; - if (yych <= 0x08) goto basic_json_parser_30; - if (yych >= '\n') goto basic_json_parser_4; - } else { - if (yych == '\r') goto basic_json_parser_2; - if (yych <= 0x1F) goto basic_json_parser_30; + + { + lexer_char_t yych; + unsigned int yyaccept = 0; + static const unsigned char yybm[] = + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 32, 0, 0, 32, 0, 0, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 96, 64, 0, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 0, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + }; + if ((m_limit - m_cursor) < 5) + { + yyfill(); // LCOV_EXCL_LINE; } - } else { - if (yych <= ',') { - if (yych == '"') goto basic_json_parser_27; - if (yych <= '+') goto basic_json_parser_30; - goto basic_json_parser_16; - } else { - if (yych <= '/') { - if (yych <= '-') goto basic_json_parser_23; - goto basic_json_parser_30; - } else { - if (yych <= '0') goto basic_json_parser_24; - if (yych <= '9') goto basic_json_parser_26; - goto basic_json_parser_18; + yych = *m_cursor; + if (yych <= ':') + { + if (yych <= ' ') + { + if (yych <= '\n') + { + if (yych <= 0x00) + { + goto basic_json_parser_28; + } + if (yych <= 0x08) + { + goto basic_json_parser_30; + } + if (yych >= '\n') + { + goto basic_json_parser_4; + } + } + else + { + if (yych == '\r') + { + goto basic_json_parser_2; + } + if (yych <= 0x1F) + { + goto basic_json_parser_30; + } + } + } + else + { + if (yych <= ',') + { + if (yych == '"') + { + goto basic_json_parser_27; + } + if (yych <= '+') + { + goto basic_json_parser_30; + } + goto basic_json_parser_16; + } + else + { + if (yych <= '/') + { + if (yych <= '-') + { + goto basic_json_parser_23; + } + goto basic_json_parser_30; + } + else + { + if (yych <= '0') + { + goto basic_json_parser_24; + } + if (yych <= '9') + { + goto basic_json_parser_26; + } + goto basic_json_parser_18; + } + } } } - } - } else { - if (yych <= 'n') { - if (yych <= ']') { - if (yych == '[') goto basic_json_parser_8; - if (yych <= '\\') goto basic_json_parser_30; - goto basic_json_parser_10; - } else { - if (yych == 'f') goto basic_json_parser_22; - if (yych <= 'm') goto basic_json_parser_30; - goto basic_json_parser_20; - } - } else { - if (yych <= '{') { - if (yych == 't') goto basic_json_parser_21; - if (yych <= 'z') goto basic_json_parser_30; - goto basic_json_parser_12; - } else { - if (yych <= '}') { - if (yych <= '|') goto basic_json_parser_30; - goto basic_json_parser_14; - } else { - if (yych == 0xEF) goto basic_json_parser_6; - goto basic_json_parser_30; + else + { + if (yych <= 'n') + { + if (yych <= ']') + { + if (yych == '[') + { + goto basic_json_parser_8; + } + if (yych <= '\\') + { + goto basic_json_parser_30; + } + goto basic_json_parser_10; + } + else + { + if (yych == 'f') + { + goto basic_json_parser_22; + } + if (yych <= 'm') + { + goto basic_json_parser_30; + } + goto basic_json_parser_20; + } + } + else + { + if (yych <= '{') + { + if (yych == 't') + { + goto basic_json_parser_21; + } + if (yych <= 'z') + { + goto basic_json_parser_30; + } + goto basic_json_parser_12; + } + else + { + if (yych <= '}') + { + if (yych <= '|') + { + goto basic_json_parser_30; + } + goto basic_json_parser_14; + } + else + { + if (yych == 0xEF) + { + goto basic_json_parser_6; + } + goto basic_json_parser_30; + } + } } } - } - } basic_json_parser_2: - ++m_cursor; - yych = *m_cursor; - goto basic_json_parser_5; + ++m_cursor; + yych = *m_cursor; + goto basic_json_parser_5; basic_json_parser_3: - { return scan(); } + { + return scan(); + } basic_json_parser_4: - ++m_cursor; - if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; - yych = *m_cursor; + ++m_cursor; + if (m_limit <= m_cursor) + { + yyfill(); // LCOV_EXCL_LINE; + } + yych = *m_cursor; basic_json_parser_5: - if (yybm[0+yych] & 32) { - goto basic_json_parser_4; - } - goto basic_json_parser_3; + if (yybm[0 + yych] & 32) + { + goto basic_json_parser_4; + } + goto basic_json_parser_3; basic_json_parser_6: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 0xBB) goto basic_json_parser_64; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 0xBB) + { + goto basic_json_parser_64; + } basic_json_parser_7: - { return token_type::parse_error; } + { + return token_type::parse_error; + } basic_json_parser_8: - ++m_cursor; - { return token_type::begin_array; } + ++m_cursor; + { + return token_type::begin_array; + } basic_json_parser_10: - ++m_cursor; - { return token_type::end_array; } + ++m_cursor; + { + return token_type::end_array; + } basic_json_parser_12: - ++m_cursor; - { return token_type::begin_object; } + ++m_cursor; + { + return token_type::begin_object; + } basic_json_parser_14: - ++m_cursor; - { return token_type::end_object; } + ++m_cursor; + { + return token_type::end_object; + } basic_json_parser_16: - ++m_cursor; - { return token_type::value_separator; } + ++m_cursor; + { + return token_type::value_separator; + } basic_json_parser_18: - ++m_cursor; - { return token_type::name_separator; } + ++m_cursor; + { + return token_type::name_separator; + } basic_json_parser_20: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'u') goto basic_json_parser_60; - goto basic_json_parser_7; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'u') + { + goto basic_json_parser_60; + } + goto basic_json_parser_7; basic_json_parser_21: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'r') goto basic_json_parser_56; - goto basic_json_parser_7; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'r') + { + goto basic_json_parser_56; + } + goto basic_json_parser_7; basic_json_parser_22: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'a') goto basic_json_parser_51; - goto basic_json_parser_7; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'a') + { + goto basic_json_parser_51; + } + goto basic_json_parser_7; basic_json_parser_23: - yych = *++m_cursor; - if (yych <= '/') goto basic_json_parser_7; - if (yych <= '0') goto basic_json_parser_50; - if (yych <= '9') goto basic_json_parser_41; - goto basic_json_parser_7; + yych = *++m_cursor; + if (yych <= '/') + { + goto basic_json_parser_7; + } + if (yych <= '0') + { + goto basic_json_parser_50; + } + if (yych <= '9') + { + goto basic_json_parser_41; + } + goto basic_json_parser_7; basic_json_parser_24: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - if (yych <= 'D') { - if (yych == '.') goto basic_json_parser_43; - } else { - if (yych <= 'E') goto basic_json_parser_44; - if (yych == 'e') goto basic_json_parser_44; - } + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + if (yych <= 'D') + { + if (yych == '.') + { + goto basic_json_parser_43; + } + } + else + { + if (yych <= 'E') + { + goto basic_json_parser_44; + } + if (yych == 'e') + { + goto basic_json_parser_44; + } + } basic_json_parser_25: - { return token_type::value_number; } + { + return token_type::value_number; + } basic_json_parser_26: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - goto basic_json_parser_42; + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + goto basic_json_parser_42; basic_json_parser_27: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych <= 0x0F) goto basic_json_parser_7; - goto basic_json_parser_32; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych <= 0x0F) + { + goto basic_json_parser_7; + } + goto basic_json_parser_32; basic_json_parser_28: - ++m_cursor; - { return token_type::end_of_input; } + ++m_cursor; + { + return token_type::end_of_input; + } basic_json_parser_30: - yych = *++m_cursor; - goto basic_json_parser_7; + yych = *++m_cursor; + goto basic_json_parser_7; basic_json_parser_31: - ++m_cursor; - if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; - yych = *m_cursor; + ++m_cursor; + if (m_limit <= m_cursor) + { + yyfill(); // LCOV_EXCL_LINE; + } + yych = *m_cursor; basic_json_parser_32: - if (yybm[0+yych] & 64) { - goto basic_json_parser_31; - } - if (yych <= 0x0F) goto basic_json_parser_33; - if (yych <= '"') goto basic_json_parser_35; - goto basic_json_parser_34; -basic_json_parser_33: - m_cursor = m_marker; - if (yyaccept == 0) { - goto basic_json_parser_7; - } else { - goto basic_json_parser_25; - } -basic_json_parser_34: - ++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; - goto basic_json_parser_31; - } else { - if (yych <= '\\') { - if (yych <= '[') goto basic_json_parser_33; + if (yybm[0 + yych] & 64) + { goto basic_json_parser_31; - } else { - if (yych == 'b') goto basic_json_parser_31; + } + if (yych <= 0x0F) + { 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 <= 'r') goto basic_json_parser_31; - goto basic_json_parser_33; - } else { - if (yych <= 't') goto basic_json_parser_31; - if (yych <= 'u') goto basic_json_parser_37; - goto basic_json_parser_33; + if (yych <= '"') + { + goto basic_json_parser_35; + } + goto basic_json_parser_34; +basic_json_parser_33: + m_cursor = m_marker; + if (yyaccept == 0) + { + goto basic_json_parser_7; + } + else + { + goto basic_json_parser_25; + } +basic_json_parser_34: + ++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; + } + goto basic_json_parser_31; + } + else + { + if (yych <= '\\') + { + if (yych <= '[') + { + goto basic_json_parser_33; + } + goto basic_json_parser_31; + } + 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 <= 'r') + { + goto basic_json_parser_31; + } + goto basic_json_parser_33; + } + else + { + if (yych <= 't') + { + goto basic_json_parser_31; + } + if (yych <= 'u') + { + goto basic_json_parser_37; + } + goto basic_json_parser_33; + } + } } - } - } basic_json_parser_35: - ++m_cursor; - { return token_type::value_string; } + ++m_cursor; + { + return token_type::value_string; + } basic_json_parser_37: - ++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 >= ':') goto basic_json_parser_33; - } else { - if (yych <= 'F') goto basic_json_parser_38; - if (yych <= '`') goto basic_json_parser_33; - if (yych >= 'g') goto basic_json_parser_33; - } + ++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 >= ':') + { + goto basic_json_parser_33; + } + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_38; + } + if (yych <= '`') + { + goto basic_json_parser_33; + } + if (yych >= 'g') + { + goto basic_json_parser_33; + } + } basic_json_parser_38: - ++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 >= ':') goto basic_json_parser_33; - } else { - if (yych <= 'F') goto basic_json_parser_39; - if (yych <= '`') goto basic_json_parser_33; - if (yych >= 'g') goto basic_json_parser_33; - } + ++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 >= ':') + { + goto basic_json_parser_33; + } + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_39; + } + if (yych <= '`') + { + goto basic_json_parser_33; + } + if (yych >= 'g') + { + goto basic_json_parser_33; + } + } basic_json_parser_39: - ++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 >= ':') goto basic_json_parser_33; - } else { - if (yych <= 'F') goto basic_json_parser_40; - if (yych <= '`') goto basic_json_parser_33; - if (yych >= 'g') goto basic_json_parser_33; - } + ++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 >= ':') + { + goto basic_json_parser_33; + } + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_40; + } + if (yych <= '`') + { + goto basic_json_parser_33; + } + if (yych >= 'g') + { + goto basic_json_parser_33; + } + } basic_json_parser_40: - ++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; - } 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; - } + ++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; + } + 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; + } basic_json_parser_41: - yyaccept = 1; - m_marker = ++m_cursor; - if ((m_limit - m_cursor) < 3) yyfill(); // LCOV_EXCL_LINE; - yych = *m_cursor; + yyaccept = 1; + m_marker = ++m_cursor; + if ((m_limit - m_cursor) < 3) + { + yyfill(); // LCOV_EXCL_LINE; + } + yych = *m_cursor; basic_json_parser_42: - if (yybm[0+yych] & 128) { - goto basic_json_parser_41; - } - if (yych <= 'D') { - if (yych != '.') goto basic_json_parser_25; - } else { - if (yych <= 'E') goto basic_json_parser_44; - if (yych == 'e') goto basic_json_parser_44; - goto basic_json_parser_25; - } + if (yybm[0 + yych] & 128) + { + goto basic_json_parser_41; + } + if (yych <= 'D') + { + if (yych != '.') + { + goto basic_json_parser_25; + } + } + else + { + if (yych <= 'E') + { + goto basic_json_parser_44; + } + if (yych == 'e') + { + goto basic_json_parser_44; + } + goto basic_json_parser_25; + } basic_json_parser_43: - yych = *++m_cursor; - if (yych <= '/') goto basic_json_parser_33; - if (yych <= '9') goto basic_json_parser_48; - goto basic_json_parser_33; + yych = *++m_cursor; + if (yych <= '/') + { + goto basic_json_parser_33; + } + if (yych <= '9') + { + goto basic_json_parser_48; + } + goto basic_json_parser_33; basic_json_parser_44: - yych = *++m_cursor; - if (yych <= ',') { - if (yych != '+') goto basic_json_parser_33; - } else { - if (yych <= '-') goto basic_json_parser_45; - if (yych <= '/') goto basic_json_parser_33; - if (yych <= '9') goto basic_json_parser_46; - goto basic_json_parser_33; - } + yych = *++m_cursor; + if (yych <= ',') + { + if (yych != '+') + { + goto basic_json_parser_33; + } + } + else + { + if (yych <= '-') + { + goto basic_json_parser_45; + } + if (yych <= '/') + { + goto basic_json_parser_33; + } + if (yych <= '9') + { + goto basic_json_parser_46; + } + goto basic_json_parser_33; + } basic_json_parser_45: - yych = *++m_cursor; - if (yych <= '/') goto basic_json_parser_33; - if (yych >= ':') goto basic_json_parser_33; + yych = *++m_cursor; + if (yych <= '/') + { + goto basic_json_parser_33; + } + if (yych >= ':') + { + goto basic_json_parser_33; + } basic_json_parser_46: - ++m_cursor; - if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; - yych = *m_cursor; - if (yych <= '/') goto basic_json_parser_25; - if (yych <= '9') goto basic_json_parser_46; - goto basic_json_parser_25; + ++m_cursor; + if (m_limit <= m_cursor) + { + yyfill(); // LCOV_EXCL_LINE; + } + yych = *m_cursor; + if (yych <= '/') + { + goto basic_json_parser_25; + } + if (yych <= '9') + { + goto basic_json_parser_46; + } + goto basic_json_parser_25; basic_json_parser_48: - 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_25; - if (yych <= '9') goto basic_json_parser_48; - goto basic_json_parser_25; - } else { - if (yych <= 'E') goto basic_json_parser_44; - if (yych == 'e') goto basic_json_parser_44; - goto basic_json_parser_25; - } + 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_25; + } + if (yych <= '9') + { + goto basic_json_parser_48; + } + goto basic_json_parser_25; + } + else + { + if (yych <= 'E') + { + goto basic_json_parser_44; + } + if (yych == 'e') + { + goto basic_json_parser_44; + } + goto basic_json_parser_25; + } basic_json_parser_50: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - if (yych <= 'D') { - if (yych == '.') goto basic_json_parser_43; - goto basic_json_parser_25; - } else { - if (yych <= 'E') goto basic_json_parser_44; - if (yych == 'e') goto basic_json_parser_44; - goto basic_json_parser_25; - } + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + if (yych <= 'D') + { + if (yych == '.') + { + goto basic_json_parser_43; + } + goto basic_json_parser_25; + } + else + { + if (yych <= 'E') + { + goto basic_json_parser_44; + } + if (yych == 'e') + { + goto basic_json_parser_44; + } + goto basic_json_parser_25; + } basic_json_parser_51: - yych = *++m_cursor; - if (yych != 'l') goto basic_json_parser_33; - yych = *++m_cursor; - if (yych != 's') goto basic_json_parser_33; - yych = *++m_cursor; - if (yych != 'e') goto basic_json_parser_33; - ++m_cursor; - { return token_type::literal_false; } + yych = *++m_cursor; + if (yych != 'l') + { + goto basic_json_parser_33; + } + yych = *++m_cursor; + if (yych != 's') + { + goto basic_json_parser_33; + } + yych = *++m_cursor; + if (yych != 'e') + { + goto basic_json_parser_33; + } + ++m_cursor; + { + return token_type::literal_false; + } basic_json_parser_56: - yych = *++m_cursor; - if (yych != 'u') goto basic_json_parser_33; - yych = *++m_cursor; - if (yych != 'e') goto basic_json_parser_33; - ++m_cursor; - { return token_type::literal_true; } + yych = *++m_cursor; + if (yych != 'u') + { + goto basic_json_parser_33; + } + yych = *++m_cursor; + if (yych != 'e') + { + goto basic_json_parser_33; + } + ++m_cursor; + { + return token_type::literal_true; + } basic_json_parser_60: - yych = *++m_cursor; - if (yych != 'l') goto basic_json_parser_33; - yych = *++m_cursor; - if (yych != 'l') goto basic_json_parser_33; - ++m_cursor; - { return token_type::literal_null; } + yych = *++m_cursor; + if (yych != 'l') + { + goto basic_json_parser_33; + } + yych = *++m_cursor; + if (yych != 'l') + { + goto basic_json_parser_33; + } + ++m_cursor; + { + return token_type::literal_null; + } basic_json_parser_64: - yych = *++m_cursor; - if (yych != 0xBF) goto basic_json_parser_33; - ++m_cursor; - { return scan(); } - } + yych = *++m_cursor; + if (yych != 0xBF) + { + goto basic_json_parser_33; + } + ++m_cursor; + { + return scan(); + } + } } @@ -7708,17 +8114,17 @@ basic_json_parser_64: /*! @brief static_cast between two types and indicate if it results in error - This function performs a static_cast between @a source and @a dest. It + This function performs a static_cast between @a source and @a dest. It then checks if a static_cast back to @a dest produces an error. - @param[in] source the value to cast from + @param[in] source the value to cast from @param[out] dest the value to cast to @return @a true if the cast was performed without error, @a false otherwise */ template - bool attempt_cast(T_A source, T_B & dest) const + bool attempt_cast(T_A source, T_B& dest) const { dest = static_cast(source); return (source == static_cast(dest)); @@ -7727,74 +8133,101 @@ basic_json_parser_64: /*! @brief return number value for number tokens - This function translates the last token into the most appropriate - number type (either integer, unsigned integer or floating point), - which is passed back to the caller via the result parameter. The pointer - @a m_start points to the beginning of the parsed number. We first examine + This function translates the last token into the most appropriate + number type (either integer, unsigned integer or floating point), which + is passed back to the caller via the result parameter. The pointer @a + m_start points to the beginning of the parsed number. We first examine the first character to determine the sign of the number and then pass - this pointer to either @a std::strtoull (if positive) or @a std::strtoll - (if negative), both of which set @a endptr to the first character past the - converted number. If this pointer is not the same as @a m_cursor, then - either more or less characters have been used during the comparison. - - This can happen for inputs like "01" which will be treated like number 0 - followed by number 1. This will also occur for valid floating point - inputs like "12e3" will be incorrectly read as 12. Numbers that are too + this pointer to either @a std::strtoull (if positive) or @a + std::strtoll (if negative), both of which set @a endptr to the first + character past the converted number. If this pointer is not the same as + @a m_cursor, then either more or less characters have been used during + the comparison. + + This can happen for inputs like "01" which will be treated like number + 0 followed by number 1. This will also occur for valid floating point + inputs like "12e3" will be incorrectly read as 12. Numbers that are too large or too small for a signed/unsigned long long will cause a range error (@a errno set to ERANGE). The parsed number is cast to a @ref - number_integer_t/@ref number_unsigned_t using the helper function @ref attempt_cast, - which returns @a false if the cast could not be peformed without error. + number_integer_t/@ref number_unsigned_t using the helper function @ref + attempt_cast, which returns @a false if the cast could not be peformed + without error. In any of these cases (more/less characters read, range error or a cast - error) the pointer is passed to @a std:strtod, which also sets @a endptr to the - first character past the converted number. The resulting @ref number_float_t - is then cast to a @ref number_integer_t/@ref number_unsigned_t using - @ref attempt_cast and if no error occurs is stored in that form, otherwise - it is stored as a @ref number_float_t. - - A final comparison is made of @a endptr and if still not the same as - @ref m_cursor a bad input is assumed and @a result parameter is set to NAN. + error) the pointer is passed to @a std:strtod, which also sets @a + endptr to the first character past the converted number. The resulting + @ref number_float_t is then cast to a @ref number_integer_t/@ref + number_unsigned_t using @ref attempt_cast and if no error occurs is + stored in that form, otherwise it is stored as a @ref number_float_t. - @param[out] result @ref basic_json object to receive the number, or NAN if the - conversion read past the current token. The latter case needs to be - treated by the caller function. + A final comparison is made of @a endptr and if still not the same as + @ref m_cursor a bad input is assumed and @a result parameter is set to + NAN. + + @param[out] result @ref basic_json object to receive the number, or NAN + if the conversion read past the current token. The latter case needs to + be treated by the caller function. */ void get_number(basic_json& result) const { typename string_t::value_type* endptr; assert(m_start != nullptr); errno = 0; - - // Attempt to parse it as an integer - first checking for a negative number + + // attempt to parse it as an integer - first checking for a + // negative number if (*reinterpret_cast(m_start) != '-') { - // Positive, parse with strtoull and attempt cast to number_unsigned_t - if (attempt_cast(std::strtoull(reinterpret_cast(m_start), &endptr, 10), result.m_value.number_unsigned)) + // positive, parse with strtoull and attempt cast to + // number_unsigned_t + if (attempt_cast(std::strtoull(reinterpret_cast(m_start), &endptr, + 10), result.m_value.number_unsigned)) + { result.m_type = value_t::number_unsigned; - else result.m_type = value_t::number_float; // Cast failed due to overflow - store as float + } + else + { + // cast failed due to overflow - store as float + result.m_type = value_t::number_float; + } } else { - // Negative, parse with strtoll and attempt cast to number_integer_t - if (attempt_cast(std::strtoll(reinterpret_cast(m_start), &endptr, 10), result.m_value.number_unsigned)) + // Negative, parse with strtoll and attempt cast to + // number_integer_t + if (attempt_cast(std::strtoll(reinterpret_cast(m_start), &endptr, + 10), result.m_value.number_unsigned)) + { result.m_type = value_t::number_integer; - else result.m_type = value_t::number_float; // Cast failed due to overflow - store as float + } + else + { + // cast failed due to overflow - store as float + result.m_type = value_t::number_float; + } } - // Check the end of the number was reached and no range error occurred - if (reinterpret_cast(endptr) != m_cursor || errno == ERANGE) result.m_type = value_t::number_float; + // check the end of the number was reached and no range error + // occurred + if (reinterpret_cast(endptr) != m_cursor || errno == ERANGE) + { + result.m_type = value_t::number_float; + } if (result.m_type == value_t::number_float) { - // Either the number won't fit in an integer (range error from strtoull/strtoll or overflow on cast) or there was - // something else after the number, which could be an exponent - - // Parse with strtod + // either the number won't fit in an integer (range error from + // strtoull/strtoll or overflow on cast) or there was something + // else after the number, which could be an exponent + + // parse with strtod result.m_value.number_float = str_to_float_t(static_cast(nullptr), &endptr); - // Anything after the number is an error - if(reinterpret_cast(endptr) != m_cursor) + // anything after the number is an error + if (reinterpret_cast(endptr) != m_cursor) + { throw std::invalid_argument(std::string("parse error - ") + get_token() + " is not a number"); + } } } @@ -8166,5 +8599,3 @@ inline nlohmann::json operator "" _json(const char* s, std::size_t) #endif #endif - - diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index d76f8ca25..52bdc1618 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -124,8 +124,8 @@ default; will be used in @ref string_t) in @ref boolean_t) @tparam NumberIntegerType type for JSON integer numbers (@c `int64_t` by default; will be used in @ref number_integer_t) -@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c `uint64_t` by -default; will be used in @ref number_unsigned_t) +@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c +`uint64_t` by default; will be used in @ref number_unsigned_t) @tparam NumberFloatType type for JSON floating-point numbers (@c `double` by default; will be used in @ref number_float_t) @tparam AllocatorType type of the allocator to use (@c `std::allocator` by @@ -485,9 +485,9 @@ class basic_json > permitted. This description includes both integer and floating-point numbers. However, - C++ allows more precise storage if it is known whether the number is a + C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, - three different types, @ref number_integer_t, @ref number_unsigned_t and + three different types, @ref number_integer_t, @ref number_unsigned_t and @ref number_float_t are used. To store integer numbers in C++, a type is defined by the template @@ -556,9 +556,9 @@ class basic_json > permitted. This description includes both integer and floating-point numbers. However, - C++ allows more precise storage if it is known whether the number is a + C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, - three different types, @ref number_integer_t, @ref number_unsigned_t and + three different types, @ref number_integer_t, @ref number_unsigned_t and @ref number_float_t are used. To store unsigned integer numbers in C++, a type is defined by the template @@ -588,11 +588,11 @@ class basic_json > An implementation may set limits on the range and precision of numbers. When the default type is used, the maximal integer number that can be - stored is `18446744073709551615` (UINT64_MAX) and the minimal integer number - that can be stored is `0`. Integer numbers - that are out of range will yield over/underflow when used in a constructor. - During deserialization, too large or small integer numbers will be - automatically be stored as @ref number_integer_t or @ref number_float_t. + stored is `18446744073709551615` (UINT64_MAX) and the minimal integer + number that can be stored is `0`. Integer numbers that are out of range + will yield over/underflow when used in a constructor. During + deserialization, too large or small integer numbers will be automatically + be stored as @ref number_integer_t or @ref number_float_t. [RFC 7159](http://rfc7159.net/rfc7159) further states: > Note that when such software is used, numbers that are integers and are @@ -600,7 +600,7 @@ class basic_json > that implementations will agree exactly on their numeric values. As this range is a subrange (when considered in conjunction with the - number_integer_t type) of the exactly supported range [0, UINT64_MAX], this + number_integer_t type) of the exactly supported range [0, UINT64_MAX], this class's integer type is interoperable. #### Storage @@ -614,7 +614,7 @@ class basic_json @since version 2.0.0 */ using number_unsigned_t = NumberUnsignedType; - + /*! @brief a type for a number (floating-point) @@ -628,9 +628,9 @@ class basic_json > permitted. This description includes both integer and floating-point numbers. However, - C++ allows more precise storage if it is known whether the number is a + C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer or a floating-point number. Therefore, - three different types, @ref number_integer_t, @ref number_unsigned_t and + three different types, @ref number_integer_t, @ref number_unsigned_t and @ref number_float_t are used. To store floating-point numbers in C++, a type is defined by the template @@ -801,7 +801,7 @@ class basic_json number_integer = number_integer_t(0); break; } - + case value_t::number_unsigned: { number_unsigned = number_unsigned_t(0); @@ -1330,8 +1330,8 @@ class basic_json template::value and - std::numeric_limits::is_integer and - std::numeric_limits::is_signed, + std::numeric_limits::is_integer and + std::numeric_limits::is_signed, CompatibleNumberIntegerType>::type = 0> basic_json(const CompatibleNumberIntegerType val) noexcept @@ -1344,7 +1344,7 @@ class basic_json Create an unsigned integer number JSON value with a given content. - @tparam T helper type to compare number_unsigned_t and unsigned int + @tparam T helper type to compare number_unsigned_t and unsigned int (not visible in) the interface. @param[in] val an integer to create a JSON number from @@ -1365,14 +1365,14 @@ class basic_json basic_json(const number_unsigned_t val) : m_type(value_t::number_unsigned), m_value(val) {} - + /*! @brief create an unsigned number (implicit) Create an unsigned number JSON value with a given content. This constructor allows any type that can be used to construct values of type @ref - number_unsigned_t. Examples may include the types `unsigned int`, `uint32_t`, - or `unsigned short`. + number_unsigned_t. Examples may include the types `unsigned int`, + `uint32_t`, or `unsigned short`. @tparam CompatibleNumberUnsignedType an integer type which is compatible to @ref number_unsigned_t. @@ -1386,13 +1386,13 @@ class basic_json @since version 2.0.0 */ - template::value and - std::numeric_limits::is_integer and - !std::numeric_limits::is_signed, - CompatibleNumberUnsignedType>::type - = 0> + template < typename CompatibleNumberUnsignedType, typename + std::enable_if < + std::is_constructible::value and + std::numeric_limits::is_integer and + !std::numeric_limits::is_signed, + CompatibleNumberUnsignedType >::type + = 0 > basic_json(const CompatibleNumberUnsignedType val) noexcept : m_type(value_t::number_unsigned), m_value(static_cast(val)) @@ -1781,7 +1781,7 @@ class basic_json m_value.number_integer = first.m_object->m_value.number_integer; break; } - + case value_t::number_unsigned: { assert(first.m_object != nullptr); @@ -1891,7 +1891,7 @@ class basic_json m_value = other.m_value.number_integer; break; } - + case value_t::number_unsigned: { m_value = other.m_value.number_unsigned; @@ -2183,9 +2183,10 @@ class basic_json @liveexample{The following code exemplifies @ref is_number for all JSON types.,is_number} - @sa @ref is_number_integer() -- check if value is an integer or unsigned + @sa @ref is_number_integer() -- check if value is an integer or unsigned integer number - @sa @ref is_number_unsigned() -- check if value is an unsigned integer number + @sa @ref is_number_unsigned() -- check if value is an unsigned integer + number @sa @ref is_number_float() -- check if value is a floating-point number @since version 1.0.0 @@ -2198,10 +2199,10 @@ class basic_json /*! @brief return whether value is an integer number - This function returns true iff the JSON value is an integer or unsigned + This function returns true iff the JSON value is an integer or unsigned integer number. This excludes floating-point values. - @return `true` if type is an integer or unsigned integer number, `false` + @return `true` if type is an integer or unsigned integer number, `false` otherwise. @complexity Constant. @@ -2210,7 +2211,8 @@ class basic_json JSON types.,is_number_integer} @sa @ref is_number() -- check if value is a number - @sa @ref is_number_unsigned() -- check if value is an unsigned integer number + @sa @ref is_number_unsigned() -- check if value is an unsigned integer + number @sa @ref is_number_float() -- check if value is a floating-point number @since version 1.0.0 @@ -2219,19 +2221,19 @@ class basic_json { return m_type == value_t::number_integer or m_type == value_t::number_unsigned; } - + /*! @brief return whether value is an unsigned integer number - This function returns true iff the JSON value is an unsigned integer number. - This excludes floating-point and (signed) integer values. + This function returns true iff the JSON value is an unsigned integer + number. This excludes floating-point and (signed) integer values. @return `true` if type is an unsigned integer number, `false` otherwise. @complexity Constant. @sa @ref is_number() -- check if value is a number - @sa @ref is_number_integer() -- check if value is an integer or unsigned + @sa @ref is_number_integer() -- check if value is an integer or unsigned integer number @sa @ref is_number_float() -- check if value is a floating-point number @@ -2257,7 +2259,8 @@ class basic_json @sa @ref is_number() -- check if value is number @sa @ref is_number_integer() -- check if value is an integer number - @sa @ref is_number_unsigned() -- check if value is an unsigned integer number + @sa @ref is_number_unsigned() -- check if value is an unsigned integer + number @since version 1.0.0 */ @@ -2525,7 +2528,7 @@ class basic_json { return static_cast(m_value.number_integer); } - + case value_t::number_unsigned: { return static_cast(m_value.number_unsigned); @@ -2615,7 +2618,7 @@ class basic_json { return is_number_integer() ? &m_value.number_integer : nullptr; } - + /// get a pointer to the value (unsigned number) number_unsigned_t* get_impl_ptr(number_unsigned_t*) noexcept { @@ -2627,7 +2630,7 @@ class basic_json { return is_number_unsigned() ? &m_value.number_unsigned : nullptr; } - + /// get a pointer to the value (floating-point number) number_float_t* get_impl_ptr(number_float_t*) noexcept { @@ -2725,7 +2728,7 @@ class basic_json @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, + object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, @ref number_unsigned_t, or @ref number_float_t. @return pointer to the internally stored JSON value if the requested @@ -2776,7 +2779,7 @@ class basic_json state. @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, + object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, @ref number_unsigned_t, or @ref number_float_t. @return pointer to the internally stored JSON value if the requested @@ -2895,14 +2898,14 @@ class basic_json @since version 1.0.0 */ - template::value - and not std::is_same::value + template < typename ValueType, typename + std::enable_if < + not std::is_pointer::value + and not std::is_same::value #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 - and not std::is_same>::value + and not std::is_same>::value #endif - , int>::type = 0> + , int >::type = 0 > operator ValueType() const { // delegate the call to get<>() const @@ -7390,17 +7393,17 @@ class basic_json /*! @brief static_cast between two types and indicate if it results in error - This function performs a static_cast between @a source and @a dest. It + This function performs a static_cast between @a source and @a dest. It then checks if a static_cast back to @a dest produces an error. - @param[in] source the value to cast from + @param[in] source the value to cast from @param[out] dest the value to cast to @return @a true if the cast was performed without error, @a false otherwise */ template - bool attempt_cast(T_A source, T_B & dest) const + bool attempt_cast(T_A source, T_B& dest) const { dest = static_cast(source); return (source == static_cast(dest)); @@ -7409,74 +7412,101 @@ class basic_json /*! @brief return number value for number tokens - This function translates the last token into the most appropriate - number type (either integer, unsigned integer or floating point), - which is passed back to the caller via the result parameter. The pointer - @a m_start points to the beginning of the parsed number. We first examine + This function translates the last token into the most appropriate + number type (either integer, unsigned integer or floating point), which + is passed back to the caller via the result parameter. The pointer @a + m_start points to the beginning of the parsed number. We first examine the first character to determine the sign of the number and then pass - this pointer to either @a std::strtoull (if positive) or @a std::strtoll - (if negative), both of which set @a endptr to the first character past the - converted number. If this pointer is not the same as @a m_cursor, then - either more or less characters have been used during the comparison. - - This can happen for inputs like "01" which will be treated like number 0 - followed by number 1. This will also occur for valid floating point - inputs like "12e3" will be incorrectly read as 12. Numbers that are too + this pointer to either @a std::strtoull (if positive) or @a + std::strtoll (if negative), both of which set @a endptr to the first + character past the converted number. If this pointer is not the same as + @a m_cursor, then either more or less characters have been used during + the comparison. + + This can happen for inputs like "01" which will be treated like number + 0 followed by number 1. This will also occur for valid floating point + inputs like "12e3" will be incorrectly read as 12. Numbers that are too large or too small for a signed/unsigned long long will cause a range error (@a errno set to ERANGE). The parsed number is cast to a @ref - number_integer_t/@ref number_unsigned_t using the helper function @ref attempt_cast, - which returns @a false if the cast could not be peformed without error. + number_integer_t/@ref number_unsigned_t using the helper function @ref + attempt_cast, which returns @a false if the cast could not be peformed + without error. In any of these cases (more/less characters read, range error or a cast - error) the pointer is passed to @a std:strtod, which also sets @a endptr to the - first character past the converted number. The resulting @ref number_float_t - is then cast to a @ref number_integer_t/@ref number_unsigned_t using - @ref attempt_cast and if no error occurs is stored in that form, otherwise - it is stored as a @ref number_float_t. - - A final comparison is made of @a endptr and if still not the same as - @ref m_cursor a bad input is assumed and @a result parameter is set to NAN. + error) the pointer is passed to @a std:strtod, which also sets @a + endptr to the first character past the converted number. The resulting + @ref number_float_t is then cast to a @ref number_integer_t/@ref + number_unsigned_t using @ref attempt_cast and if no error occurs is + stored in that form, otherwise it is stored as a @ref number_float_t. - @param[out] result @ref basic_json object to receive the number, or NAN if the - conversion read past the current token. The latter case needs to be - treated by the caller function. + A final comparison is made of @a endptr and if still not the same as + @ref m_cursor a bad input is assumed and @a result parameter is set to + NAN. + + @param[out] result @ref basic_json object to receive the number, or NAN + if the conversion read past the current token. The latter case needs to + be treated by the caller function. */ void get_number(basic_json& result) const { typename string_t::value_type* endptr; assert(m_start != nullptr); errno = 0; - - // Attempt to parse it as an integer - first checking for a negative number + + // attempt to parse it as an integer - first checking for a + // negative number if (*reinterpret_cast(m_start) != '-') { - // Positive, parse with strtoull and attempt cast to number_unsigned_t - if (attempt_cast(std::strtoull(reinterpret_cast(m_start), &endptr, 10), result.m_value.number_unsigned)) + // positive, parse with strtoull and attempt cast to + // number_unsigned_t + if (attempt_cast(std::strtoull(reinterpret_cast(m_start), &endptr, + 10), result.m_value.number_unsigned)) + { result.m_type = value_t::number_unsigned; - else result.m_type = value_t::number_float; // Cast failed due to overflow - store as float + } + else + { + // cast failed due to overflow - store as float + result.m_type = value_t::number_float; + } } else { - // Negative, parse with strtoll and attempt cast to number_integer_t - if (attempt_cast(std::strtoll(reinterpret_cast(m_start), &endptr, 10), result.m_value.number_unsigned)) + // Negative, parse with strtoll and attempt cast to + // number_integer_t + if (attempt_cast(std::strtoll(reinterpret_cast(m_start), &endptr, + 10), result.m_value.number_unsigned)) + { result.m_type = value_t::number_integer; - else result.m_type = value_t::number_float; // Cast failed due to overflow - store as float + } + else + { + // cast failed due to overflow - store as float + result.m_type = value_t::number_float; + } } - // Check the end of the number was reached and no range error occurred - if (reinterpret_cast(endptr) != m_cursor || errno == ERANGE) result.m_type = value_t::number_float; + // check the end of the number was reached and no range error + // occurred + if (reinterpret_cast(endptr) != m_cursor || errno == ERANGE) + { + result.m_type = value_t::number_float; + } if (result.m_type == value_t::number_float) { - // Either the number won't fit in an integer (range error from strtoull/strtoll or overflow on cast) or there was - // something else after the number, which could be an exponent - - // Parse with strtod + // either the number won't fit in an integer (range error from + // strtoull/strtoll or overflow on cast) or there was something + // else after the number, which could be an exponent + + // parse with strtod result.m_value.number_float = str_to_float_t(static_cast(nullptr), &endptr); - // Anything after the number is an error - if(reinterpret_cast(endptr) != m_cursor) + // anything after the number is an error + if (reinterpret_cast(endptr) != m_cursor) + { throw std::invalid_argument(std::string("parse error - ") + get_token() + " is not a number"); + } } } @@ -7848,5 +7878,3 @@ inline nlohmann::json operator "" _json(const char* s, std::size_t) #endif #endif - - diff --git a/test/unit.cpp b/test/unit.cpp index 519f760b9..507c55cca 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -924,7 +924,8 @@ TEST_CASE("constructors") SECTION("object with error") { - CHECK_THROWS_AS(json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }), std::logic_error); + CHECK_THROWS_AS(json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }), + std::logic_error); CHECK_THROWS_WITH(json::object({ {"one", 1}, {"two", 1u}, {"three", 2.2}, {"four", false}, 13 }), "cannot create object from initializer list"); } @@ -2312,7 +2313,7 @@ TEST_CASE("value conversion") json::number_integer_t n = j.get(); CHECK(json(n) == j); } - + SECTION("number_unsigned_t") { json::number_unsigned_t n = j_unsigned.get(); @@ -3665,7 +3666,7 @@ TEST_CASE("element access") CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with number"); } - + SECTION("number (unsigned)") { json j_nonobject(json::value_t::number_unsigned); @@ -3675,7 +3676,7 @@ TEST_CASE("element access") CHECK_THROWS_WITH(j_nonobject.at("foo"), "cannot use at() with number"); CHECK_THROWS_WITH(j_nonobject_const.at("foo"), "cannot use at() with number"); } - + SECTION("number (floating-point)") { json j_nonobject(json::value_t::number_float); @@ -5435,7 +5436,7 @@ TEST_CASE("iterators") SECTION("object") { - json j = {{"A", 1},{"B", 2},{"C", 3}}; + json j = {{"A", 1}, {"B", 2}, {"C", 3}}; json j_const(j); SECTION("json + begin/end") @@ -9661,7 +9662,7 @@ TEST_CASE("parser class") // (2**53)-1 CHECK(json::parser("9007199254740991").parse().get() == 9007199254740991); } - + SECTION("over the edge cases") // issue #178 - Integer conversion to unsigned (incorrect handling of 64 bit integers) { // While RFC7159, Section 6 specifies a preference for support @@ -9672,7 +9673,7 @@ TEST_CASE("parser class") // i.e. -(2**63) -> (2**64)-1. // -(2**63) ** Note: compilers see negative literals as negated positive numbers (hence the -1)) - CHECK(json::parser("-9223372036854775808").parse().get() == -9223372036854775807-1); + CHECK(json::parser("-9223372036854775808").parse().get() == -9223372036854775807 - 1); // (2**63)-1 CHECK(json::parser("9223372036854775807").parse().get() == 9223372036854775807); // (2**64)-1 @@ -9720,12 +9721,14 @@ TEST_CASE("parser class") CHECK_THROWS_WITH(json::parser("01").parse(), "parse error - 0 is not a number"); CHECK_THROWS_WITH(json::parser("--1").parse(), "parse error - unexpected '-'"); - CHECK_THROWS_WITH(json::parser("1.").parse(), "parse error - unexpected '.'; expected end of input"); + CHECK_THROWS_WITH(json::parser("1.").parse(), + "parse error - unexpected '.'; expected end of input"); CHECK_THROWS_WITH(json::parser("1E").parse(), "parse error - unexpected 'E'; expected end of input"); CHECK_THROWS_WITH(json::parser("1E-").parse(), "parse error - unexpected 'E'; expected end of input"); - CHECK_THROWS_WITH(json::parser("1.E1").parse(), "parse error - unexpected '.'; expected end of input"); + CHECK_THROWS_WITH(json::parser("1.E1").parse(), + "parse error - unexpected '.'; expected end of input"); CHECK_THROWS_WITH(json::parser("-1E").parse(), "parse error - unexpected 'E'; expected end of input"); CHECK_THROWS_WITH(json::parser("-0E#").parse(), @@ -9767,7 +9770,8 @@ TEST_CASE("parser class") CHECK_THROWS_AS(json::parser("1E.").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("1E/").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("1E:").parse(), std::invalid_argument); - CHECK_THROWS_WITH(json::parser("0.").parse(), "parse error - unexpected '.'; expected end of input"); + CHECK_THROWS_WITH(json::parser("0.").parse(), + "parse error - unexpected '.'; expected end of input"); CHECK_THROWS_WITH(json::parser("-").parse(), "parse error - unexpected '-'"); CHECK_THROWS_WITH(json::parser("--").parse(), "parse error - unexpected '-'"); @@ -12076,14 +12080,15 @@ TEST_CASE("regression tests") SECTION("issue #89 - nonstandard integer type") { // create JSON class with nonstandard integer number type - using custom_json = nlohmann::basic_json; + using custom_json = + nlohmann::basic_json; custom_json j; j["int_1"] = 1; // we need to cast to int to compile with Catch - the value is int32_t CHECK(static_cast(j["int_1"]) == 1); // tests for correct handling of non-standard integers that overflow the type selected by the user - + // unsigned integer object creation - expected to wrap and still be stored as an integer j = 4294967296U; // 2^32 CHECK(static_cast(j.type()) == static_cast(custom_json::value_t::number_unsigned)); @@ -12201,11 +12206,11 @@ TEST_CASE("regression tests") { CHECK(json::parse("\"\\ud80c\\udc60abc\"").get() == u8"\U00013060abc"); } - + SECTION("issue #171 - Cannot index by key of type static constexpr const char*") { json j; - + // Non-const access with key as "char []" char array_key[] = "Key1"; CHECK_NOTHROW(j[array_key] = 1); @@ -12281,15 +12286,18 @@ TEST_CASE("regression tests") // create JSON class with nonstandard float number type // float - nlohmann::basic_json j_float = 1.23e25f; + nlohmann::basic_json j_float = + 1.23e25f; CHECK(j_float.get() == 1.23e25f); // double - nlohmann::basic_json j_double = 1.23e35f; + nlohmann::basic_json j_double = + 1.23e35f; CHECK(j_double.get() == 1.23e35f); // long double - nlohmann::basic_json j_long_double = 1.23e45L; + nlohmann::basic_json + j_long_double = 1.23e45L; CHECK(j_long_double.get() == 1.23e45L); } } From 2468631dc9407ce0be46e96e720d628e1b38b967 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 26 Jan 2016 20:07:03 +0100 Subject: [PATCH 12/18] overworked examples --- README.md | 2 +- doc/Doxyfile | 2 +- doc/examples/README.link | 2 +- doc/examples/is_array.cpp | 2 ++ doc/examples/is_array.link | 2 +- doc/examples/is_array.output | 1 + doc/examples/is_boolean.cpp | 2 ++ doc/examples/is_boolean.link | 2 +- doc/examples/is_boolean.output | 1 + doc/examples/is_discarded.cpp | 2 ++ doc/examples/is_discarded.link | 2 +- doc/examples/is_discarded.output | 1 + doc/examples/is_null.cpp | 2 ++ doc/examples/is_null.link | 2 +- doc/examples/is_null.output | 1 + doc/examples/is_number.cpp | 2 ++ doc/examples/is_number.link | 2 +- doc/examples/is_number.output | 1 + doc/examples/is_number_float.cpp | 2 ++ doc/examples/is_number_float.link | 2 +- doc/examples/is_number_float.output | 1 + doc/examples/is_number_integer.cpp | 2 ++ doc/examples/is_number_integer.link | 2 +- doc/examples/is_number_integer.output | 1 + doc/examples/is_number_unsigned.cpp | 27 ++++++++++++++++++++++++++ doc/examples/is_number_unsigned.link | 1 + doc/examples/is_number_unsigned.output | 8 ++++++++ doc/examples/is_object.cpp | 2 ++ doc/examples/is_object.link | 2 +- doc/examples/is_object.output | 1 + doc/examples/is_primitive.cpp | 2 ++ doc/examples/is_primitive.link | 2 +- doc/examples/is_primitive.output | 1 + doc/examples/is_string.cpp | 2 ++ doc/examples/is_string.link | 2 +- doc/examples/is_string.output | 1 + doc/examples/is_structured.cpp | 2 ++ doc/examples/is_structured.link | 2 +- doc/examples/is_structured.output | 1 + src/json.hpp | 5 ++++- src/json.hpp.re2c | 5 ++++- 41 files changed, 91 insertions(+), 16 deletions(-) create mode 100644 doc/examples/is_number_unsigned.cpp create mode 100644 doc/examples/is_number_unsigned.link create mode 100644 doc/examples/is_number_unsigned.output diff --git a/README.md b/README.md index 8d180c282..cc6ff3be8 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ There are myriads of [JSON](http://json.org) libraries out there, and each may e Other aspects were not so important to us: -- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs. +- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs. - **Speed**. We currently implement the parser as naive [recursive descent parser](http://en.wikipedia.org/wiki/Recursive_descent_parser) with hand coded string handling. It is fast enough, but a [LALR-parser](http://en.wikipedia.org/wiki/LALR_parser) with a decent regular expression processor should be even faster (but would consist of more files which makes the integration harder). diff --git a/doc/Doxyfile b/doc/Doxyfile index a97cb5add..f1b3b3670 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "JSON for Modern C++" -PROJECT_NUMBER = 1.1.0 +PROJECT_NUMBER = 2.0.0 PROJECT_BRIEF = PROJECT_LOGO = OUTPUT_DIRECTORY = . diff --git a/doc/examples/README.link b/doc/examples/README.link index 96f5ad8a4..dab9343fb 100644 --- a/doc/examples/README.link +++ b/doc/examples/README.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_array.cpp b/doc/examples/is_array.cpp index a5a544f03..c436f38f4 100644 --- a/doc/examples/is_array.cpp +++ b/doc/examples/is_array.cpp @@ -8,6 +8,7 @@ int main() json j_null; json j_boolean = true; json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; json j_number_float = 23.42; json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; @@ -18,6 +19,7 @@ int main() std::cout << j_null.is_array() << '\n'; std::cout << j_boolean.is_array() << '\n'; std::cout << j_number_integer.is_array() << '\n'; + std::cout << j_number_unsigned_integer.is_array() << '\n'; std::cout << j_number_float.is_array() << '\n'; std::cout << j_object.is_array() << '\n'; std::cout << j_array.is_array() << '\n'; diff --git a/doc/examples/is_array.link b/doc/examples/is_array.link index e1aa234e7..4d5fdb07f 100644 --- a/doc/examples/is_array.link +++ b/doc/examples/is_array.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_array.output b/doc/examples/is_array.output index 65ffc69e1..5b8cc40c9 100644 --- a/doc/examples/is_array.output +++ b/doc/examples/is_array.output @@ -3,5 +3,6 @@ false false false false +false true false diff --git a/doc/examples/is_boolean.cpp b/doc/examples/is_boolean.cpp index 0143b0bf4..24511a2fd 100644 --- a/doc/examples/is_boolean.cpp +++ b/doc/examples/is_boolean.cpp @@ -8,6 +8,7 @@ int main() json j_null; json j_boolean = true; json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; json j_number_float = 23.42; json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; @@ -18,6 +19,7 @@ int main() std::cout << j_null.is_boolean() << '\n'; std::cout << j_boolean.is_boolean() << '\n'; std::cout << j_number_integer.is_boolean() << '\n'; + std::cout << j_number_unsigned_integer.is_boolean() << '\n'; std::cout << j_number_float.is_boolean() << '\n'; std::cout << j_object.is_boolean() << '\n'; std::cout << j_array.is_boolean() << '\n'; diff --git a/doc/examples/is_boolean.link b/doc/examples/is_boolean.link index 3972af75b..5fda3d0a8 100644 --- a/doc/examples/is_boolean.link +++ b/doc/examples/is_boolean.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_boolean.output b/doc/examples/is_boolean.output index 54f16b97f..721b3a5e2 100644 --- a/doc/examples/is_boolean.output +++ b/doc/examples/is_boolean.output @@ -5,3 +5,4 @@ false false false false +false diff --git a/doc/examples/is_discarded.cpp b/doc/examples/is_discarded.cpp index c71bf901c..7f6c8c07b 100644 --- a/doc/examples/is_discarded.cpp +++ b/doc/examples/is_discarded.cpp @@ -8,6 +8,7 @@ int main() json j_null; json j_boolean = true; json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; json j_number_float = 23.42; json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; @@ -18,6 +19,7 @@ int main() std::cout << j_null.is_discarded() << '\n'; std::cout << j_boolean.is_discarded() << '\n'; std::cout << j_number_integer.is_discarded() << '\n'; + std::cout << j_number_unsigned_integer.is_discarded() << '\n'; std::cout << j_number_float.is_discarded() << '\n'; std::cout << j_object.is_discarded() << '\n'; std::cout << j_array.is_discarded() << '\n'; diff --git a/doc/examples/is_discarded.link b/doc/examples/is_discarded.link index 389f90bbb..5f58643d7 100644 --- a/doc/examples/is_discarded.link +++ b/doc/examples/is_discarded.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_discarded.output b/doc/examples/is_discarded.output index 28f6ac44f..485b16967 100644 --- a/doc/examples/is_discarded.output +++ b/doc/examples/is_discarded.output @@ -5,3 +5,4 @@ false false false false +false diff --git a/doc/examples/is_null.cpp b/doc/examples/is_null.cpp index d107f7302..d6a6de4c7 100644 --- a/doc/examples/is_null.cpp +++ b/doc/examples/is_null.cpp @@ -8,6 +8,7 @@ int main() json j_null; json j_boolean = true; json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; json j_number_float = 23.42; json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; @@ -18,6 +19,7 @@ int main() std::cout << j_null.is_null() << '\n'; std::cout << j_boolean.is_null() << '\n'; std::cout << j_number_integer.is_null() << '\n'; + std::cout << j_number_unsigned_integer.is_null() << '\n'; std::cout << j_number_float.is_null() << '\n'; std::cout << j_object.is_null() << '\n'; std::cout << j_array.is_null() << '\n'; diff --git a/doc/examples/is_null.link b/doc/examples/is_null.link index a2fb14074..39c5d2611 100644 --- a/doc/examples/is_null.link +++ b/doc/examples/is_null.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_null.output b/doc/examples/is_null.output index 828ea8919..4cc64628d 100644 --- a/doc/examples/is_null.output +++ b/doc/examples/is_null.output @@ -5,3 +5,4 @@ false false false false +false diff --git a/doc/examples/is_number.cpp b/doc/examples/is_number.cpp index 992ec1838..29c21ffba 100644 --- a/doc/examples/is_number.cpp +++ b/doc/examples/is_number.cpp @@ -8,6 +8,7 @@ int main() json j_null; json j_boolean = true; json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; json j_number_float = 23.42; json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; @@ -18,6 +19,7 @@ int main() std::cout << j_null.is_number() << '\n'; std::cout << j_boolean.is_number() << '\n'; std::cout << j_number_integer.is_number() << '\n'; + std::cout << j_number_unsigned_integer.is_number() << '\n'; std::cout << j_number_float.is_number() << '\n'; std::cout << j_object.is_number() << '\n'; std::cout << j_array.is_number() << '\n'; diff --git a/doc/examples/is_number.link b/doc/examples/is_number.link index 1fc0fc866..090b5ca92 100644 --- a/doc/examples/is_number.link +++ b/doc/examples/is_number.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_number.output b/doc/examples/is_number.output index b031a1411..06dbc2823 100644 --- a/doc/examples/is_number.output +++ b/doc/examples/is_number.output @@ -2,6 +2,7 @@ false false true true +true false false false diff --git a/doc/examples/is_number_float.cpp b/doc/examples/is_number_float.cpp index 3ede378fa..289428c3e 100644 --- a/doc/examples/is_number_float.cpp +++ b/doc/examples/is_number_float.cpp @@ -8,6 +8,7 @@ int main() json j_null; json j_boolean = true; json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; json j_number_float = 23.42; json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; @@ -18,6 +19,7 @@ int main() std::cout << j_null.is_number_float() << '\n'; std::cout << j_boolean.is_number_float() << '\n'; std::cout << j_number_integer.is_number_float() << '\n'; + std::cout << j_number_unsigned_integer.is_number_float() << '\n'; std::cout << j_number_float.is_number_float() << '\n'; std::cout << j_object.is_number_float() << '\n'; std::cout << j_array.is_number_float() << '\n'; diff --git a/doc/examples/is_number_float.link b/doc/examples/is_number_float.link index ef3aaf331..7ed767603 100644 --- a/doc/examples/is_number_float.link +++ b/doc/examples/is_number_float.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_number_float.output b/doc/examples/is_number_float.output index c24702822..09afae4c9 100644 --- a/doc/examples/is_number_float.output +++ b/doc/examples/is_number_float.output @@ -1,6 +1,7 @@ false false false +false true false false diff --git a/doc/examples/is_number_integer.cpp b/doc/examples/is_number_integer.cpp index 281bf432c..d7a38b6ad 100644 --- a/doc/examples/is_number_integer.cpp +++ b/doc/examples/is_number_integer.cpp @@ -8,6 +8,7 @@ int main() json j_null; json j_boolean = true; json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; json j_number_float = 23.42; json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; @@ -18,6 +19,7 @@ int main() std::cout << j_null.is_number_integer() << '\n'; std::cout << j_boolean.is_number_integer() << '\n'; std::cout << j_number_integer.is_number_integer() << '\n'; + std::cout << j_number_unsigned_integer.is_number_integer() << '\n'; std::cout << j_number_float.is_number_integer() << '\n'; std::cout << j_object.is_number_integer() << '\n'; std::cout << j_array.is_number_integer() << '\n'; diff --git a/doc/examples/is_number_integer.link b/doc/examples/is_number_integer.link index bbd368f04..fae1ef433 100644 --- a/doc/examples/is_number_integer.link +++ b/doc/examples/is_number_integer.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_number_integer.output b/doc/examples/is_number_integer.output index 26051afd7..be0f73936 100644 --- a/doc/examples/is_number_integer.output +++ b/doc/examples/is_number_integer.output @@ -1,6 +1,7 @@ false false true +true false false false diff --git a/doc/examples/is_number_unsigned.cpp b/doc/examples/is_number_unsigned.cpp new file mode 100644 index 000000000..185d93de7 --- /dev/null +++ b/doc/examples/is_number_unsigned.cpp @@ -0,0 +1,27 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call is_number_unsigned() + std::cout << std::boolalpha; + std::cout << j_null.is_number_unsigned() << '\n'; + std::cout << j_boolean.is_number_unsigned() << '\n'; + std::cout << j_number_integer.is_number_unsigned() << '\n'; + std::cout << j_number_unsigned_integer.is_number_unsigned() << '\n'; + std::cout << j_number_float.is_number_unsigned() << '\n'; + std::cout << j_object.is_number_unsigned() << '\n'; + std::cout << j_array.is_number_unsigned() << '\n'; + std::cout << j_string.is_number_unsigned() << '\n'; +} diff --git a/doc/examples/is_number_unsigned.link b/doc/examples/is_number_unsigned.link new file mode 100644 index 000000000..1877ced96 --- /dev/null +++ b/doc/examples/is_number_unsigned.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/is_number_unsigned.output b/doc/examples/is_number_unsigned.output new file mode 100644 index 000000000..fdf264e0c --- /dev/null +++ b/doc/examples/is_number_unsigned.output @@ -0,0 +1,8 @@ +false +false +false +true +false +false +false +false diff --git a/doc/examples/is_object.cpp b/doc/examples/is_object.cpp index 268c02244..b85253a3b 100644 --- a/doc/examples/is_object.cpp +++ b/doc/examples/is_object.cpp @@ -9,6 +9,7 @@ int main() json j_boolean = true; json j_number_integer = 17; json j_number_float = 23.42; + json j_number_unsigned_integer = 12345678987654321u; json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; @@ -18,6 +19,7 @@ int main() std::cout << j_null.is_object() << '\n'; std::cout << j_boolean.is_object() << '\n'; std::cout << j_number_integer.is_object() << '\n'; + std::cout << j_number_unsigned_integer.is_object() << '\n'; std::cout << j_number_float.is_object() << '\n'; std::cout << j_object.is_object() << '\n'; std::cout << j_array.is_object() << '\n'; diff --git a/doc/examples/is_object.link b/doc/examples/is_object.link index 5ab6384fc..549bc0c0f 100644 --- a/doc/examples/is_object.link +++ b/doc/examples/is_object.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_object.output b/doc/examples/is_object.output index 8416200cd..e041e3922 100644 --- a/doc/examples/is_object.output +++ b/doc/examples/is_object.output @@ -2,6 +2,7 @@ false false false false +false true false false diff --git a/doc/examples/is_primitive.cpp b/doc/examples/is_primitive.cpp index ed5d8b0bb..3f45b95a5 100644 --- a/doc/examples/is_primitive.cpp +++ b/doc/examples/is_primitive.cpp @@ -9,6 +9,7 @@ int main() json j_boolean = true; json j_number_integer = 17; json j_number_float = 23.42; + json j_number_unsigned_integer = 12345678987654321u; json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; @@ -18,6 +19,7 @@ int main() std::cout << j_null.is_primitive() << '\n'; std::cout << j_boolean.is_primitive() << '\n'; std::cout << j_number_integer.is_primitive() << '\n'; + std::cout << j_number_unsigned_integer.is_primitive() << '\n'; std::cout << j_number_float.is_primitive() << '\n'; std::cout << j_object.is_primitive() << '\n'; std::cout << j_array.is_primitive() << '\n'; diff --git a/doc/examples/is_primitive.link b/doc/examples/is_primitive.link index f6918a96d..27167a3a4 100644 --- a/doc/examples/is_primitive.link +++ b/doc/examples/is_primitive.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_primitive.output b/doc/examples/is_primitive.output index 2c1bd2528..635db6e34 100644 --- a/doc/examples/is_primitive.output +++ b/doc/examples/is_primitive.output @@ -2,6 +2,7 @@ true true true true +true false false true diff --git a/doc/examples/is_string.cpp b/doc/examples/is_string.cpp index 6bcbcec51..6020fb668 100644 --- a/doc/examples/is_string.cpp +++ b/doc/examples/is_string.cpp @@ -9,6 +9,7 @@ int main() json j_boolean = true; json j_number_integer = 17; json j_number_float = 23.42; + json j_number_unsigned_integer = 12345678987654321u; json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; @@ -18,6 +19,7 @@ int main() std::cout << j_null.is_string() << '\n'; std::cout << j_boolean.is_string() << '\n'; std::cout << j_number_integer.is_string() << '\n'; + std::cout << j_number_unsigned_integer.is_string() << '\n'; std::cout << j_number_float.is_string() << '\n'; std::cout << j_object.is_string() << '\n'; std::cout << j_array.is_string() << '\n'; diff --git a/doc/examples/is_string.link b/doc/examples/is_string.link index 7ba95c364..1e8d54fa3 100644 --- a/doc/examples/is_string.link +++ b/doc/examples/is_string.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_string.output b/doc/examples/is_string.output index 2cead02b6..672eb4385 100644 --- a/doc/examples/is_string.output +++ b/doc/examples/is_string.output @@ -4,4 +4,5 @@ false false false false +false true diff --git a/doc/examples/is_structured.cpp b/doc/examples/is_structured.cpp index 13c183e80..40a7cb332 100644 --- a/doc/examples/is_structured.cpp +++ b/doc/examples/is_structured.cpp @@ -9,6 +9,7 @@ int main() json j_boolean = true; json j_number_integer = 17; json j_number_float = 23.42; + json j_number_unsigned_integer = 12345678987654321u; json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; @@ -18,6 +19,7 @@ int main() std::cout << j_null.is_structured() << '\n'; std::cout << j_boolean.is_structured() << '\n'; std::cout << j_number_integer.is_structured() << '\n'; + std::cout << j_number_unsigned_integer.is_structured() << '\n'; std::cout << j_number_float.is_structured() << '\n'; std::cout << j_object.is_structured() << '\n'; std::cout << j_array.is_structured() << '\n'; diff --git a/doc/examples/is_structured.link b/doc/examples/is_structured.link index 9b5abfdf3..6cc3c9bba 100644 --- a/doc/examples/is_structured.link +++ b/doc/examples/is_structured.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_structured.output b/doc/examples/is_structured.output index d251407d8..e1186dd8f 100644 --- a/doc/examples/is_structured.output +++ b/doc/examples/is_structured.output @@ -2,6 +2,7 @@ false false false false +false true true false diff --git a/src/json.hpp b/src/json.hpp index 8b8ed337b..0a2c6fde0 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -32,7 +32,7 @@ Class @ref nlohmann::basic_json is a good entry point for the documentation. @author [Niels Lohmann](http://nlohmann.me) @see https://github.com/nlohmann/json to download the source code -@version 1.1.0 +@version 2.0.0 */ #ifndef NLOHMANN_JSON_HPP @@ -2232,6 +2232,9 @@ class basic_json @complexity Constant. + @liveexample{The following code exemplifies @ref is_number_unsigned for all + JSON types.,is_number_unsigned} + @sa @ref is_number() -- check if value is a number @sa @ref is_number_integer() -- check if value is an integer or unsigned integer number diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 52bdc1618..c80a2bea2 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -32,7 +32,7 @@ Class @ref nlohmann::basic_json is a good entry point for the documentation. @author [Niels Lohmann](http://nlohmann.me) @see https://github.com/nlohmann/json to download the source code -@version 1.1.0 +@version 2.0.0 */ #ifndef NLOHMANN_JSON_HPP @@ -2232,6 +2232,9 @@ class basic_json @complexity Constant. + @liveexample{The following code exemplifies @ref is_number_unsigned for all + JSON types.,is_number_unsigned} + @sa @ref is_number() -- check if value is a number @sa @ref is_number_integer() -- check if value is an integer or unsigned integer number From fb239fe6451405b8581eb14adbdb09eeec0cd391 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 26 Jan 2016 21:42:51 +0100 Subject: [PATCH 13/18] trying Gitter --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cc6ff3be8..4979a20a9 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT) [![Github Releases](https://img.shields.io/github/release/nlohmann/json.svg)](https://github.com/nlohmann/json/releases) [![Github Issues](https://img.shields.io/github/issues/nlohmann/json.svg)](http://github.com/nlohmann/json/issues) +[![Gitter](https://badges.gitter.im/nlohmann/json.svg)](https://gitter.im/nlohmann/json?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) ## Design goals From 91c58a77a1b5d2a9d87c12aa3127bc348237fedd Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 26 Jan 2016 21:49:20 +0100 Subject: [PATCH 14/18] added Gitter to Travis --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index 2b75fc436..629bec876 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,3 +57,11 @@ script: - make CXX=$COMPILER CXXFLAGS="-lstdc++" - ./json_unit "*" - valgrind --error-exitcode=1 --leak-check=full ./json_unit + +notifications: + webhooks: + urls: + - https://webhooks.gitter.im/e/f1196addb0e97a5ff396 + on_success: change + on_failure: always + on_start: never From 89b07bd3aff1bb74e275f77250f5595e6a916ed3 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 26 Jan 2016 22:59:57 +0100 Subject: [PATCH 15/18] added (generated) changelog --- ChangeLog.md | 180 +++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 10 ++- doc/ChangeLog.md | 45 ------------ 3 files changed, 189 insertions(+), 46 deletions(-) create mode 100644 ChangeLog.md delete mode 100644 doc/ChangeLog.md diff --git a/ChangeLog.md b/ChangeLog.md new file mode 100644 index 000000000..f8cf18dc5 --- /dev/null +++ b/ChangeLog.md @@ -0,0 +1,180 @@ +# Change Log + +## [Unreleased](https://github.com/nlohmann/json/tree/HEAD) + +[Full Changelog](https://github.com/nlohmann/json/compare/v1.1.0...HEAD) + +- Issue \#178 - Extending support to full uint64\_t/int64\_t range and unsigned type \(updated\) [\#193](https://github.com/nlohmann/json/pull/193) ([twelsby](https://github.com/twelsby)) + +- GCC/clang floating point parsing bug in strtod\(\) [\#195](https://github.com/nlohmann/json/issues/195) +- Floating point exceptions [\#181](https://github.com/nlohmann/json/issues/181) +- Implicit assignment to std::string fails [\#144](https://github.com/nlohmann/json/issues/144) +- Issue \#195 - update Travis to Trusty due to gcc/clang strtod\(\) bug [\#196](https://github.com/nlohmann/json/pull/196) ([twelsby](https://github.com/twelsby)) + +- Integer conversion to unsigned [\#178](https://github.com/nlohmann/json/issues/178) + +- Fix broken link [\#197](https://github.com/nlohmann/json/pull/197) ([vog](https://github.com/vog)) + +## [v1.1.0](https://github.com/nlohmann/json/tree/v1.1.0) (2016-01-24) +[Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0...v1.1.0) + +- JSON performance benchmark comparision [\#177](https://github.com/nlohmann/json/issues/177) +- Since re2c is often ignored in pull requests, it may make sense to make a contributing.md file [\#175](https://github.com/nlohmann/json/issues/175) +- Add assertions [\#168](https://github.com/nlohmann/json/issues/168) +- range based for loop for objects [\#83](https://github.com/nlohmann/json/issues/83) +- Implementation of get\_ref\(\) [\#184](https://github.com/nlohmann/json/pull/184) ([dariomt](https://github.com/dariomt)) + +- Small error in pull \#185 [\#194](https://github.com/nlohmann/json/issues/194) +- Bugs in miloyip/nativejson-benchmark: floating-point parsing [\#186](https://github.com/nlohmann/json/issues/186) +- Cannot index by key of type static constexpr const char\* [\#171](https://github.com/nlohmann/json/issues/171) +- Fixed Issue \#171 - added two extra template overloads of operator\[\] for T\* arguments [\#189](https://github.com/nlohmann/json/pull/189) ([twelsby](https://github.com/twelsby)) +- Fixed issue \#167 - removed operator ValueType\(\) condition for VS2015 [\#188](https://github.com/nlohmann/json/pull/188) ([twelsby](https://github.com/twelsby)) + +- Floating point equality [\#185](https://github.com/nlohmann/json/issues/185) +- Unused variables in catch [\#180](https://github.com/nlohmann/json/issues/180) +- Typo in documentation [\#179](https://github.com/nlohmann/json/issues/179) +- Android? [\#172](https://github.com/nlohmann/json/issues/172) +- MSVC 2015 build fails when attempting to compare object\_t [\#167](https://github.com/nlohmann/json/issues/167) +- Member detector is not portable [\#166](https://github.com/nlohmann/json/issues/166) +- Unnecessary const\_cast [\#162](https://github.com/nlohmann/json/issues/162) +- Consider submitting this to the Boost Library Incubator [\#66](https://github.com/nlohmann/json/issues/66) + +- Fixed Issue \#186 - add strto\(f|d|ld\) overload wrappers, "-0.0" special case and FP trailing zero [\#191](https://github.com/nlohmann/json/pull/191) ([twelsby](https://github.com/twelsby)) +- Issue \#185 - remove approx\(\) and use \#pragma to kill warnings [\#190](https://github.com/nlohmann/json/pull/190) ([twelsby](https://github.com/twelsby)) +- Fixed some typos in CONTRIBUTING.md [\#182](https://github.com/nlohmann/json/pull/182) ([nibroc](https://github.com/nibroc)) + +## [v1.0.0](https://github.com/nlohmann/json/tree/v1.0.0) (2015-12-27) +[Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0-rc1...v1.0.0) + +- add key name to exception [\#160](https://github.com/nlohmann/json/issues/160) +- prevent json.hpp from emitting compiler warnings [\#154](https://github.com/nlohmann/json/issues/154) +- json::parse\(string\) does not check utf8 bom [\#152](https://github.com/nlohmann/json/issues/152) +- unsigned 64bit values output as signed [\#151](https://github.com/nlohmann/json/issues/151) +- Wish feature: json5 [\#150](https://github.com/nlohmann/json/issues/150) +- overload of at\(\) with default value [\#133](https://github.com/nlohmann/json/issues/133) +- Memory leak in face of exceptions [\#118](https://github.com/nlohmann/json/issues/118) +- Find and Count for arrays [\#117](https://github.com/nlohmann/json/issues/117) +- dynamically constructing an arbitrarily nested object [\#114](https://github.com/nlohmann/json/issues/114) +- object field accessors [\#103](https://github.com/nlohmann/json/issues/103) +- v8pp and json [\#95](https://github.com/nlohmann/json/issues/95) +- Wishlist [\#65](https://github.com/nlohmann/json/issues/65) +- Windows/Visual Studio \(through 2013\) is unsupported [\#62](https://github.com/nlohmann/json/issues/62) + +- Bug in basic\_json::operator\[\] const overload [\#135](https://github.com/nlohmann/json/issues/135) +- wrong enable\_if for const pointer \(instead of pointer-to-const\) [\#134](https://github.com/nlohmann/json/issues/134) +- Visual Studio 14 Debug assertion failed [\#125](https://github.com/nlohmann/json/issues/125) +- Compile error with g++ 4.9.3 cygwin 64-bit [\#112](https://github.com/nlohmann/json/issues/112) +- error: unterminated raw string [\#109](https://github.com/nlohmann/json/issues/109) +- \[clang-3.6.2\] string/sstream with number to json issue [\#107](https://github.com/nlohmann/json/issues/107) + +- Getting member discarding qualifyer [\#159](https://github.com/nlohmann/json/issues/159) +- basic\_json::iterator::value\(\) output includes quotes while basic\_json::iterator::key\(\) doesn't [\#158](https://github.com/nlohmann/json/issues/158) +- Indexing `const basic\_json\<\>` with `const basic\_string\` [\#157](https://github.com/nlohmann/json/issues/157) +- token\_type\_name\(token\_type t\): not all control paths return a value [\#156](https://github.com/nlohmann/json/issues/156) +- Unable to compile on MSVC 2015 with SDL checking enabled: This function or variable may be unsafe. [\#149](https://github.com/nlohmann/json/issues/149) +- dump\(\) convert strings encoded by utf-8 to shift-jis on windows 10. [\#147](https://github.com/nlohmann/json/issues/147) +- Unable to get field names in a json object [\#145](https://github.com/nlohmann/json/issues/145) +- json.hpp:5746:32: error: 'to\_string' is not a member of 'std' [\#136](https://github.com/nlohmann/json/issues/136) +- Returning any data type [\#113](https://github.com/nlohmann/json/issues/113) +- vector\ copy constructor really weird [\#108](https://github.com/nlohmann/json/issues/108) +- maintaining order of keys during iteration [\#106](https://github.com/nlohmann/json/issues/106) + +- Replace sprintf with hex function, this fixes \#149 [\#153](https://github.com/nlohmann/json/pull/153) ([whackashoe](https://github.com/whackashoe)) +- Fix character skipping after a surrogate pair [\#146](https://github.com/nlohmann/json/pull/146) ([robertmrk](https://github.com/robertmrk)) +- Detect correctly pointer-to-const [\#137](https://github.com/nlohmann/json/pull/137) ([dariomt](https://github.com/dariomt)) +- disabled "CopyAssignable" test for MSVC in Debug mode, see \#125 [\#131](https://github.com/nlohmann/json/pull/131) ([dariomt](https://github.com/dariomt)) +- removed stream operator for iterator, resolution for \#125 [\#130](https://github.com/nlohmann/json/pull/130) ([dariomt](https://github.com/dariomt)) +- fixed typos in comments for examples [\#129](https://github.com/nlohmann/json/pull/129) ([dariomt](https://github.com/dariomt)) +- Remove superfluous inefficiency [\#126](https://github.com/nlohmann/json/pull/126) ([d-frey](https://github.com/d-frey)) +- remove invalid parameter '-stdlib=libc++' in CMakeLists.txt [\#124](https://github.com/nlohmann/json/pull/124) ([emvivre](https://github.com/emvivre)) +- exception-safe object creation, fixes \#118 [\#122](https://github.com/nlohmann/json/pull/122) ([d-frey](https://github.com/d-frey)) +- Fix small oversight. [\#121](https://github.com/nlohmann/json/pull/121) ([ColinH](https://github.com/ColinH)) +- Overload parse\(\) to accept an rvalue reference [\#120](https://github.com/nlohmann/json/pull/120) ([silverweed](https://github.com/silverweed)) +- Use the right variable name in doc string [\#115](https://github.com/nlohmann/json/pull/115) ([whoshuu](https://github.com/whoshuu)) + +## [v1.0.0-rc1](https://github.com/nlohmann/json/tree/v1.0.0-rc1) (2015-07-26) +- Adjust wording to JSON RFC [\#97](https://github.com/nlohmann/json/issues/97) +- access by \(const\) reference [\#91](https://github.com/nlohmann/json/issues/91) +- is\_integer and is\_float tests [\#90](https://github.com/nlohmann/json/issues/90) +- MinGW have no std::to\_string [\#80](https://github.com/nlohmann/json/issues/80) +- erase elements using iterators [\#57](https://github.com/nlohmann/json/issues/57) +- Removing item from array [\#56](https://github.com/nlohmann/json/issues/56) +- Serialize/Deserialize like PHP? [\#55](https://github.com/nlohmann/json/issues/55) +- Document erase, count, and iterators key and value [\#52](https://github.com/nlohmann/json/issues/52) +- Supported compilers [\#50](https://github.com/nlohmann/json/issues/50) +- Use non-member begin/end [\#48](https://github.com/nlohmann/json/issues/48) +- Erase key [\#47](https://github.com/nlohmann/json/issues/47) +- Key iterator [\#46](https://github.com/nlohmann/json/issues/46) +- Add count member function [\#45](https://github.com/nlohmann/json/issues/45) +- Printing attribute names [\#39](https://github.com/nlohmann/json/issues/39) +- Avoid using spaces when encoding without pretty print [\#31](https://github.com/nlohmann/json/issues/31) +- Cannot encode long numbers [\#30](https://github.com/nlohmann/json/issues/30) +- Creating an empty array [\#27](https://github.com/nlohmann/json/issues/27) +- Custom allocator support [\#25](https://github.com/nlohmann/json/issues/25) +- create a header-only version [\#16](https://github.com/nlohmann/json/issues/16) +- Add to\_string overload for indentation [\#13](https://github.com/nlohmann/json/issues/13) +- move code into namespace [\#9](https://github.com/nlohmann/json/issues/9) +- free functions for explicit objects and arrays in initializer lists [\#8](https://github.com/nlohmann/json/issues/8) +- Test case coverage [\#2](https://github.com/nlohmann/json/issues/2) +- Parse streams incrementally. [\#40](https://github.com/nlohmann/json/pull/40) ([aburgh](https://github.com/aburgh)) + +- Binary string causes numbers to be dumped as hex [\#101](https://github.com/nlohmann/json/issues/101) +- failed to iterator json object with reverse\_iterator [\#100](https://github.com/nlohmann/json/issues/100) +- static analysis warnings [\#94](https://github.com/nlohmann/json/issues/94) +- reverse\_iterator operator inheritance problem [\#93](https://github.com/nlohmann/json/issues/93) +- Nonstandard integer type [\#89](https://github.com/nlohmann/json/issues/89) +- lexer::get\_number return NAN [\#82](https://github.com/nlohmann/json/issues/82) +- Handle infinity and NaN cases [\#70](https://github.com/nlohmann/json/issues/70) +- errors in g++-4.8.1 [\#68](https://github.com/nlohmann/json/issues/68) +- Double quotation mark is not parsed correctly [\#60](https://github.com/nlohmann/json/issues/60) +- Do not use std::to\_string [\#51](https://github.com/nlohmann/json/issues/51) +- Confused about iterating through json objects [\#49](https://github.com/nlohmann/json/issues/49) +- Problem getting vector \(array\) of strings [\#44](https://github.com/nlohmann/json/issues/44) +- Compilation error due to assuming that private=public [\#43](https://github.com/nlohmann/json/issues/43) +- Use of deprecated implicit copy constructor [\#42](https://github.com/nlohmann/json/issues/42) +- dumping a small number\_float just outputs 0.000000 [\#37](https://github.com/nlohmann/json/issues/37) +- Avoid using spaces when encoding without pretty print [\#31](https://github.com/nlohmann/json/issues/31) +- Cannot encode long numbers [\#30](https://github.com/nlohmann/json/issues/30) +- segmentation fault when iterating over empty arrays/objects [\#28](https://github.com/nlohmann/json/issues/28) +- Improper parsing of JSON string "\\" [\#17](https://github.com/nlohmann/json/issues/17) +- Don't return "const values" [\#15](https://github.com/nlohmann/json/issues/15) +- string parser does not recognize uncompliant strings [\#12](https://github.com/nlohmann/json/issues/12) +- free functions for explicit objects and arrays in initializer lists [\#8](https://github.com/nlohmann/json/issues/8) +- Runtime error in Travis job [\#1](https://github.com/nlohmann/json/issues/1) +- Fix compilation of json\_unit with GCC 5 [\#59](https://github.com/nlohmann/json/pull/59) ([dkopecek](https://github.com/dkopecek)) + +- Finish documenting the public interface in Doxygen [\#102](https://github.com/nlohmann/json/issues/102) +- 'noexcept' : unknown override specifier [\#99](https://github.com/nlohmann/json/issues/99) +- Keys when iterating over objects [\#67](https://github.com/nlohmann/json/issues/67) +- Complete brief documentation [\#61](https://github.com/nlohmann/json/issues/61) +- Get coverage back to 100% [\#58](https://github.com/nlohmann/json/issues/58) +- possible double-free in find function [\#11](https://github.com/nlohmann/json/issues/11) +- UTF-8 encoding/deconding/testing [\#10](https://github.com/nlohmann/json/issues/10) +- Add unit tests [\#4](https://github.com/nlohmann/json/issues/4) +- Drop C++98 support [\#3](https://github.com/nlohmann/json/issues/3) + +- Keyword 'inline' is useless when member functions are defined in headers [\#87](https://github.com/nlohmann/json/pull/87) ([ahamez](https://github.com/ahamez)) +- Remove useless typename [\#86](https://github.com/nlohmann/json/pull/86) ([ahamez](https://github.com/ahamez)) +- Avoid warning with Xcode's clang [\#85](https://github.com/nlohmann/json/pull/85) ([ahamez](https://github.com/ahamez)) +- Fix typos [\#73](https://github.com/nlohmann/json/pull/73) ([aqnouch](https://github.com/aqnouch)) +- Replace `default\_callback` function with `nullptr` and check for null… [\#72](https://github.com/nlohmann/json/pull/72) ([aburgh](https://github.com/aburgh)) +- support enum [\#71](https://github.com/nlohmann/json/pull/71) ([likebeta](https://github.com/likebeta)) +- Fix performance regression introduced with the parsing callback feature. [\#69](https://github.com/nlohmann/json/pull/69) ([aburgh](https://github.com/aburgh)) +- Improve the implementations of the comparission-operators [\#63](https://github.com/nlohmann/json/pull/63) ([Florianjw](https://github.com/Florianjw)) +- Feature/small float serialization [\#38](https://github.com/nlohmann/json/pull/38) ([jrandall](https://github.com/jrandall)) +- template version with re2c scanner [\#36](https://github.com/nlohmann/json/pull/36) ([nlohmann](https://github.com/nlohmann)) +- more descriptive documentation in example [\#33](https://github.com/nlohmann/json/pull/33) ([luxe](https://github.com/luxe)) +- Fix string conversion under Clang [\#26](https://github.com/nlohmann/json/pull/26) ([wancw](https://github.com/wancw)) +- Fixed dumping of strings [\#24](https://github.com/nlohmann/json/pull/24) ([Teemperor](https://github.com/Teemperor)) +- Added a remark to the readme that coverage is GCC only for now [\#23](https://github.com/nlohmann/json/pull/23) ([Teemperor](https://github.com/Teemperor)) +- Unicode escaping [\#22](https://github.com/nlohmann/json/pull/22) ([Teemperor](https://github.com/Teemperor)) +- Implemented the JSON spec for string parsing for everything but the \uXXXX escaping [\#21](https://github.com/nlohmann/json/pull/21) ([Teemperor](https://github.com/Teemperor)) +- add the std iterator typedefs to iterator and const\_iterator [\#19](https://github.com/nlohmann/json/pull/19) ([kirkshoop](https://github.com/kirkshoop)) +- Fixed escaped quotes [\#18](https://github.com/nlohmann/json/pull/18) ([Teemperor](https://github.com/Teemperor)) +- Fix double delete on std::bad\_alloc exception [\#14](https://github.com/nlohmann/json/pull/14) ([elliotgoodrich](https://github.com/elliotgoodrich)) +- Added CMake and lcov [\#6](https://github.com/nlohmann/json/pull/6) ([Teemperor](https://github.com/Teemperor)) +- Version 2.0 [\#5](https://github.com/nlohmann/json/pull/5) ([nlohmann](https://github.com/nlohmann)) + + + +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file diff --git a/Makefile b/Makefile index 71a1175fd..deb645a31 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: pretty clean +.PHONY: pretty clean ChangeLog.md # used programs RE2C = re2c @@ -59,3 +59,11 @@ pretty: json_benchmarks: benchmarks/benchmarks.cpp benchmarks/benchpress.hpp benchmarks/cxxopts.hpp src/json.hpp $(CXX) -std=c++11 $(CXXFLAGS) -O3 -flto -I src -I benchmarks $< $(LDFLAGS) -o $@ ./json_benchmarks + + +########################################################################## +# changelog +########################################################################## + +ChangeLog.md: + github_changelog_generator -o ChangeLog.md --simple-list -t c4d32c07b91e0893e78a8e6aabd04f2d71fea8c8 diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md deleted file mode 100644 index a43b0e1ab..000000000 --- a/doc/ChangeLog.md +++ /dev/null @@ -1,45 +0,0 @@ -# JSON for Modern C++ - -## Version 1.0.0 - -- Release date: 2015-12-28 -- MD5: 331c30e4407ecdcf591e9e3ed85100d0 - -### Summary - -This is the first official release. Compared to the [prerelease version 1.0.0-rc1](https://github.com/nlohmann/json/releases/tag/v1.0.0-rc1), only a few minor improvements have been made: - -### Changes - -- *Changed*: A **UTF-8 byte order mark** is silently ignored. -- *Changed*: `sprintf` is no longer used. -- *Changed*: `iterator_wrapper` also works for const objects; note: the name may change! -- *Changed*: **Error messages** during deserialization have been improved. -- *Added*: The `parse` function now also works with type `std::istream&&`. -- *Added*: Function `value(key, default_value)` returns either a copy of an object's element at the specified key or a given default value if no element with the key exists. -- *Added*: Public functions are tagged with the version they were introduced. This shall allow for better **versioning** in the future. -- *Added*: All public functions and types are **documented** (see http://nlohmann.github.io/json/) including executable examples. -- *Added*: Allocation of all types (in particular arrays, strings, and objects) is now exception-safe. -- *Added*: They descriptions of thrown exceptions have been overworked and are part of the tests suite and documentation. - -## Version 1.0.0-rc1 - -- Release date: 2015-07-26 -- MD5: fac5948417ed49bfd0852a0e9dd36935 - -### Summary - -The 1.0.0 release should be the first "official" release after the initial announcement of the class in January 2015 via reddit ("0.1.0") and a heavily overworked second version ("0.2.0") in February. - -### Changes - -- *Changed:* In the generic class `basic_json`, all JSON value types (array, object, string, bool, integer number, and floating-point) are now **templated**. That is, you can choose whether you like a `std::list` for your arrays or an `std::unordered_map` for your objects. The specialization `json` sets some reasonable defaults. -- *Changed:* The library now consists of a **single header**, called `json.hpp`. Consequently, build systems such as Automake or CMake are not any longer required. -- *Changed:* The **deserialization** is now supported by a lexer generated with [re2c](http://re2c.org) from file [`src/json.hpp.re2c`](https://github.com/nlohmann/json/blob/master/src/json.hpp.re2c). As a result, we strictly follow the JSON specification. Note neither the tool re2c nor its input are required to use the class. -- *Added:* The library now satisfies the [**ReversibleContainer**](http://en.cppreference.com/w/cpp/concept/ReversibleContainer) requirement. It hence provides four different iterators (`iterator`, `const_iterator`, `reverse_iterator`, and `const_reverse_iterator`), comparison functions, `swap()`, `size()`, `max_size()`, and `empty()` member functions. -- *Added*: The class uses **user-defined allocators** which default to `std::allocator`, but can be templated via parameter `Allocator`. -- *Added:* To simplify pretty-printing, the `std::setw` **stream manipulator** has been overloaded to set the desired indentation. Pretty-printing a JSON object `j` is as simple as `std::cout << std::setw(4) << j << '\n'`. -- *Changed*: The type `json::value_t::number` is now called `json::value_t::number_integer` to be more symmetric compared to `json::value_t::number_float`. -- *Added*: The documentation is generated with Doxygen and hosted at [nlohmann.github.io/json](http://nlohmann.github.io/json/). Every public member function is thoroughly described including an example which also can be [tried online](http://melpon.org/wandbox/permlink/GnGKwji06WeVonlI). -- *Added*: The class is heavily unit-tested (3341774 assertions) and has a [line coverage of 100%](https://coveralls.io/github/nlohmann/json). With every commit, the code is compiled with g++ 4.9, g++ 5.0, Clang 3.6 (thanks to [Travis CI](https://travis-ci.org/nlohmann/json)), and Microsoft Visual Studio 14 2015 (thanks to [AppVeyor](https://ci.appveyor.com/project/nlohmann/json)). - From 1c80c2231f620c31ea41642167649a718cd7c192 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 26 Jan 2016 23:10:52 +0100 Subject: [PATCH 16/18] linked releases in ChangeLog --- ChangeLog.md | 6 +++--- Makefile | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index f8cf18dc5..68dab967f 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -15,7 +15,7 @@ - Fix broken link [\#197](https://github.com/nlohmann/json/pull/197) ([vog](https://github.com/vog)) -## [v1.1.0](https://github.com/nlohmann/json/tree/v1.1.0) (2016-01-24) +## [v1.1.0](https://github.com/nlohmann/json/releases/tag/v1.1.0) (2016-01-24) [Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0...v1.1.0) - JSON performance benchmark comparision [\#177](https://github.com/nlohmann/json/issues/177) @@ -43,7 +43,7 @@ - Issue \#185 - remove approx\(\) and use \#pragma to kill warnings [\#190](https://github.com/nlohmann/json/pull/190) ([twelsby](https://github.com/twelsby)) - Fixed some typos in CONTRIBUTING.md [\#182](https://github.com/nlohmann/json/pull/182) ([nibroc](https://github.com/nibroc)) -## [v1.0.0](https://github.com/nlohmann/json/tree/v1.0.0) (2015-12-27) +## [v1.0.0](https://github.com/nlohmann/json/releases/tag/v1.0.0) (2015-12-27) [Full Changelog](https://github.com/nlohmann/json/compare/v1.0.0-rc1...v1.0.0) - add key name to exception [\#160](https://github.com/nlohmann/json/issues/160) @@ -92,7 +92,7 @@ - Overload parse\(\) to accept an rvalue reference [\#120](https://github.com/nlohmann/json/pull/120) ([silverweed](https://github.com/silverweed)) - Use the right variable name in doc string [\#115](https://github.com/nlohmann/json/pull/115) ([whoshuu](https://github.com/whoshuu)) -## [v1.0.0-rc1](https://github.com/nlohmann/json/tree/v1.0.0-rc1) (2015-07-26) +## [v1.0.0-rc1](https://github.com/nlohmann/json/releases/tag/v1.0.0-rc1) (2015-07-26) - Adjust wording to JSON RFC [\#97](https://github.com/nlohmann/json/issues/97) - access by \(const\) reference [\#91](https://github.com/nlohmann/json/issues/91) - is\_integer and is\_float tests [\#90](https://github.com/nlohmann/json/issues/90) diff --git a/Makefile b/Makefile index deb645a31..83702afe0 100644 --- a/Makefile +++ b/Makefile @@ -66,4 +66,5 @@ json_benchmarks: benchmarks/benchmarks.cpp benchmarks/benchpress.hpp benchmarks/ ########################################################################## ChangeLog.md: - github_changelog_generator -o ChangeLog.md --simple-list -t c4d32c07b91e0893e78a8e6aabd04f2d71fea8c8 + github_changelog_generator -o ChangeLog.md --simple-list -t 6b6238b83152d6eefafe1b0dbb1e571fcf2e88e9 --release-url https://github.com/nlohmann/json/releases/tag/%s + gsed -i 's|https://github.com/nlohmann/json/releases/tag/HEAD|https://github.com/nlohmann/json/tree/HEAD|' ChangeLog.md From 3dfa56795f3d5399873182db81a6f67c766897a2 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 26 Jan 2016 23:27:07 +0100 Subject: [PATCH 17/18] added note --- ChangeLog.md | 1 + Makefile | 1 + 2 files changed, 2 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 68dab967f..81990a7b9 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,4 +1,5 @@ # 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) diff --git a/Makefile b/Makefile index 83702afe0..14e3ae9b6 100644 --- a/Makefile +++ b/Makefile @@ -68,3 +68,4 @@ json_benchmarks: benchmarks/benchmarks.cpp benchmarks/benchpress.hpp benchmarks/ ChangeLog.md: github_changelog_generator -o ChangeLog.md --simple-list -t 6b6238b83152d6eefafe1b0dbb1e571fcf2e88e9 --release-url https://github.com/nlohmann/json/releases/tag/%s gsed -i 's|https://github.com/nlohmann/json/releases/tag/HEAD|https://github.com/nlohmann/json/tree/HEAD|' ChangeLog.md + gsed -i '2i All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).' ChangeLog.md From ff6f7231958b7d078b468bf78d658e55b30b1b3a Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 26 Jan 2016 23:30:51 +0100 Subject: [PATCH 18/18] removed token --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 14e3ae9b6..fdef78408 100644 --- a/Makefile +++ b/Makefile @@ -66,6 +66,6 @@ json_benchmarks: benchmarks/benchmarks.cpp benchmarks/benchpress.hpp benchmarks/ ########################################################################## ChangeLog.md: - github_changelog_generator -o ChangeLog.md --simple-list -t 6b6238b83152d6eefafe1b0dbb1e571fcf2e88e9 --release-url https://github.com/nlohmann/json/releases/tag/%s + github_changelog_generator -o ChangeLog.md --simple-list --release-url https://github.com/nlohmann/json/releases/tag/%s gsed -i 's|https://github.com/nlohmann/json/releases/tag/HEAD|https://github.com/nlohmann/json/tree/HEAD|' ChangeLog.md gsed -i '2i All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).' ChangeLog.md