From 5dd06714b13b375acdc987b9261679d0c331b9ed Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Mon, 28 Dec 2020 11:31:21 +0100 Subject: [PATCH 01/11] :bug: allow parsing from std::byte containers #2546 --- include/nlohmann/detail/input/lexer.hpp | 6 +++--- single_include/nlohmann/json.hpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/nlohmann/detail/input/lexer.hpp b/include/nlohmann/detail/input/lexer.hpp index 0a9601352..eae82eaa3 100644 --- a/include/nlohmann/detail/input/lexer.hpp +++ b/include/nlohmann/detail/input/lexer.hpp @@ -1541,17 +1541,17 @@ scan_number_done: // literals case 't': { - std::array true_literal = {{'t', 'r', 'u', 'e'}}; + std::array true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}}; return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); } case 'f': { - std::array false_literal = {{'f', 'a', 'l', 's', 'e'}}; + std::array false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}}; return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); } case 'n': { - std::array null_literal = {{'n', 'u', 'l', 'l'}}; + std::array null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}}; return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 51fe8382b..539ebc7ad 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -7511,17 +7511,17 @@ scan_number_done: // literals case 't': { - std::array true_literal = {{'t', 'r', 'u', 'e'}}; + std::array true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}}; return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); } case 'f': { - std::array false_literal = {{'f', 'a', 'l', 's', 'e'}}; + std::array false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}}; return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); } case 'n': { - std::array null_literal = {{'n', 'u', 'l', 'l'}}; + std::array null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}}; return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); } From 7b98df515f26058308f1ea5eedb6d1525cd12630 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 14:48:18 +0100 Subject: [PATCH 02/11] :white_check_mark: add regression test --- .travis.yml | 10 ++++++++++ test/src/unit-regression2.cpp | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/.travis.yml b/.travis.yml index f48ee1fd6..c671e93f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -300,6 +300,16 @@ matrix: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-7'] packages: ['g++-7', 'clang-7', 'ninja-build'] + - os: linux + compiler: clang + env: + - COMPILER=clang++-7 + - CXX_STANDARD=20 + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-7'] + packages: ['g++-7', 'clang-7', 'ninja-build'] + ################ # build script # ################ diff --git a/test/src/unit-regression2.cpp b/test/src/unit-regression2.cpp index ca50cdd41..1171531f6 100644 --- a/test/src/unit-regression2.cpp +++ b/test/src/unit-regression2.cpp @@ -51,6 +51,10 @@ using nlohmann::json; #include #endif +#ifdef JSON_HAS_CPP_20 + #include +#endif + ///////////////////////////////////////////////////////////////////// // for #1021 ///////////////////////////////////////////////////////////////////// @@ -484,4 +488,14 @@ TEST_CASE("regression tests 2") json j = json::parse(ss, nullptr, true, true); CHECK(j.dump() == "{}"); } + +#ifdef JSON_HAS_CPP_20 + SECTION("issue #2546 - parsing containers of std::byte") + { + const char DATA[] = R"("Hello, world!")"; + const auto s = std::as_bytes(std::span(DATA)); + json j = json::parse(s); + CHECK(j.dump == "Hello, world!"); + } +#endif } From 433da313341430cf32b26f2bcdadbb67e9465ced Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 20:16:51 +0100 Subject: [PATCH 03/11] :alembic: try to use GCC 10 --- .github/workflows/ubuntu.yml | 8 ++++++ .travis.yml | 10 -------- .../nlohmann/detail/iterators/iter_impl.hpp | 25 ++++++++++++++++++- single_include/nlohmann/json.hpp | 25 ++++++++++++++++++- test/src/unit-class_parser.cpp | 2 +- test/src/unit-items.cpp | 8 ++++++ test/src/unit-regression1.cpp | 2 +- test/src/unit-udt.cpp | 14 +++++------ 8 files changed, 73 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 1a47a885c..a4742e6a1 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -8,8 +8,16 @@ jobs: steps: - uses: actions/checkout@v1 + - name: install_gcc + run: | + sudo apt update + sudo apt install gcc-10 g++-10 + shell: bash - name: cmake run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On + env: + CC: gcc-10 + CXX: g++-10 - name: build run: cmake --build build --parallel 10 - name: test diff --git a/.travis.yml b/.travis.yml index c671e93f6..f48ee1fd6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -300,16 +300,6 @@ matrix: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-7'] packages: ['g++-7', 'clang-7', 'ninja-build'] - - os: linux - compiler: clang - env: - - COMPILER=clang++-7 - - CXX_STANDARD=20 - addons: - apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-7'] - packages: ['g++-7', 'clang-7', 'ninja-build'] - ################ # build script # ################ diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp index b4faa88a5..6c65c6018 100644 --- a/include/nlohmann/detail/iterators/iter_impl.hpp +++ b/include/nlohmann/detail/iterators/iter_impl.hpp @@ -393,7 +393,30 @@ class iter_impl @brief comparison: equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - bool operator==(const iter_impl& other) const + bool operator==(const iter_impl& other) const + { + // if objects are not the same, the comparison is undefined + if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) + { + JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); + } + + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_type) + { + case value_t::object: + return (m_it.object_iterator == other.m_it.object_iterator); + + case value_t::array: + return (m_it.array_iterator == other.m_it.array_iterator); + + default: + return (m_it.primitive_iterator == other.m_it.primitive_iterator); + } + } + + bool operator==(const iter_impl::type>& other) const { // if objects are not the same, the comparison is undefined if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 765eac810..ac0568ce9 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -11279,7 +11279,30 @@ class iter_impl @brief comparison: equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - bool operator==(const iter_impl& other) const + bool operator==(const iter_impl& other) const + { + // if objects are not the same, the comparison is undefined + if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) + { + JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); + } + + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_type) + { + case value_t::object: + return (m_it.object_iterator == other.m_it.object_iterator); + + case value_t::array: + return (m_it.array_iterator == other.m_it.array_iterator); + + default: + return (m_it.primitive_iterator == other.m_it.primitive_iterator); + } + } + + bool operator==(const iter_impl::type>& other) const { // if objects are not the same, the comparison is undefined if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) diff --git a/test/src/unit-class_parser.cpp b/test/src/unit-class_parser.cpp index d0335c948..c612daabc 100644 --- a/test/src/unit-class_parser.cpp +++ b/test/src/unit-class_parser.cpp @@ -509,7 +509,7 @@ TEST_CASE("parser class") CHECK(parser_helper("\"€\"").get() == "€"); CHECK(parser_helper("\"🎈\"").get() == "🎈"); - CHECK(parser_helper("\"\\ud80c\\udc60\"").get() == u8"\U00013060"); + CHECK(parser_helper("\"\\ud80c\\udc60\"").get() == "\U00013060"); CHECK(parser_helper("\"\\ud83c\\udf1e\"").get() == "🌞"); } } diff --git a/test/src/unit-items.cpp b/test/src/unit-items.cpp index 10621ce7e..4caf76f23 100644 --- a/test/src/unit-items.cpp +++ b/test/src/unit-items.cpp @@ -1448,3 +1448,11 @@ TEST_CASE("items()") } } } + +#ifdef JSON_HAS_CPP_17 + #undef JSON_HAS_CPP_17 +#endif + +#ifdef JSON_HAS_CPP_14 + #undef JSON_HAS_CPP_14 +#endif diff --git a/test/src/unit-regression1.cpp b/test/src/unit-regression1.cpp index 9dcc75b09..f5520056f 100644 --- a/test/src/unit-regression1.cpp +++ b/test/src/unit-regression1.cpp @@ -400,7 +400,7 @@ TEST_CASE("regression tests 1") SECTION("issue #146 - character following a surrogate pair is skipped") { - CHECK(json::parse("\"\\ud80c\\udc60abc\"").get() == u8"\U00013060abc"); + CHECK(json::parse("\"\\ud80c\\udc60abc\"").get() == "\U00013060abc"); } SECTION("issue #171 - Cannot index by key of type static constexpr const char*") diff --git a/test/src/unit-udt.cpp b/test/src/unit-udt.cpp index 7f74ac5f8..b23765505 100644 --- a/test/src/unit-udt.cpp +++ b/test/src/unit-udt.cpp @@ -112,13 +112,13 @@ static void to_json(BasicJsonType& j, country c) switch (c) { case country::china: - j = u8"中华人民共和国"; + j = "中华人民共和国"; return; case country::france: j = "France"; return; case country::russia: - j = u8"Российская Федерация"; + j = "Российская Федерация"; return; default: break; @@ -201,9 +201,9 @@ static void from_json(const BasicJsonType& j, country& c) const auto str = j.template get(); static const std::map m = { - {u8"中华人民共和国", country::china}, + {"中华人民共和国", country::china}, {"France", country::france}, - {u8"Российская Федерация", country::russia} + {"Российская Федерация", country::russia} }; const auto it = m.find(str); @@ -248,7 +248,7 @@ TEST_CASE("basic usage" * doctest::test_suite("udt")) const udt::name n{"theo"}; const udt::country c{udt::country::france}; const udt::person sfinae_addict{a, n, c}; - const udt::person senior_programmer{{42}, {u8"王芳"}, udt::country::china}; + const udt::person senior_programmer{{42}, {"王芳"}, udt::country::china}; const udt::address addr{"Paris"}; const udt::contact cpp_programmer{sfinae_addict, addr}; const udt::contact_book book{{"C++"}, {cpp_programmer, {senior_programmer, addr}}}; @@ -265,14 +265,14 @@ TEST_CASE("basic usage" * doctest::test_suite("udt")) CHECK( json(book) == - u8R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json); + R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json); } SECTION("conversion from json via free-functions") { const auto big_json = - u8R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json; + R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json; SECTION("via explicit calls to get") { const auto parsed_book = big_json.get(); From ca51dc62f2a37be1a4f54a069850ffb80091a1e4 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 20:21:43 +0100 Subject: [PATCH 04/11] :alembic: try to use Clang 10 --- .github/workflows/ubuntu.yml | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index a4742e6a1..9792431ff 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -3,7 +3,7 @@ name: Ubuntu on: [push, pull_request] jobs: - build: + gcc_build: runs-on: ubuntu-latest steps: @@ -22,3 +22,23 @@ jobs: run: cmake --build build --parallel 10 - name: test run: cd build ; ctest -j 10 --output-on-failure + + clang_build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: install_gcc + run: | + sudo apt update + sudo apt install clang-10 + shell: bash + - name: cmake + run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On + env: + CC: clang-10 + CXX: clang++-10 + - name: build + run: cmake --build build --parallel 10 + - name: test + run: cd build ; ctest -j 10 --output-on-failure From 91d7aa571fbeb991813afd327ad005def52e7a0a Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 20:30:50 +0100 Subject: [PATCH 05/11] :alembic: add C++20 build --- .github/workflows/ubuntu.yml | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 9792431ff..58fdbd88f 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -42,3 +42,43 @@ jobs: run: cmake --build build --parallel 10 - name: test run: cd build ; ctest -j 10 --output-on-failure + + gcc_build_cxx20: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: install_gcc + run: | + sudo apt update + sudo apt install gcc-10 g++-10 + shell: bash + - name: cmake + run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=ON + env: + CC: gcc-10 + CXX: g++-10 + - name: build + run: cmake --build build --parallel 10 + - name: test + run: cd build ; ctest -j 10 --output-on-failure + + clang_build_cxx20: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: install_gcc + run: | + sudo apt update + sudo apt install clang-10 + shell: bash + - name: cmake + run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=ON + env: + CC: clang-10 + CXX: clang++-10 + - name: build + run: cmake --build build --parallel 10 + - name: test + run: cd build ; ctest -j 10 --output-on-failure From 77be4f6aaf2b72cf3f3ca16fce8abd3367bdc1e5 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 20:32:07 +0100 Subject: [PATCH 06/11] :alembic: add C++20 build --- .github/workflows/ubuntu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 58fdbd88f..711cf106d 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -54,7 +54,7 @@ jobs: sudo apt install gcc-10 g++-10 shell: bash - name: cmake - run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=ON + run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=ON env: CC: gcc-10 CXX: g++-10 From e4fc598466cffa49953f299c4de4a06f1c9a7392 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 20:45:56 +0100 Subject: [PATCH 07/11] :alembic: add C++20 build --- .github/workflows/ubuntu.yml | 20 -------------------- test/src/unit-regression2.cpp | 2 +- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 711cf106d..d6b654077 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -43,26 +43,6 @@ jobs: - name: test run: cd build ; ctest -j 10 --output-on-failure - gcc_build_cxx20: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v1 - - name: install_gcc - run: | - sudo apt update - sudo apt install gcc-10 g++-10 - shell: bash - - name: cmake - run: cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -DJSON_BuildTests=On -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=ON - env: - CC: gcc-10 - CXX: g++-10 - - name: build - run: cmake --build build --parallel 10 - - name: test - run: cd build ; ctest -j 10 --output-on-failure - clang_build_cxx20: runs-on: ubuntu-latest diff --git a/test/src/unit-regression2.cpp b/test/src/unit-regression2.cpp index 1171531f6..86320f039 100644 --- a/test/src/unit-regression2.cpp +++ b/test/src/unit-regression2.cpp @@ -495,7 +495,7 @@ TEST_CASE("regression tests 2") const char DATA[] = R"("Hello, world!")"; const auto s = std::as_bytes(std::span(DATA)); json j = json::parse(s); - CHECK(j.dump == "Hello, world!"); + CHECK(j.dump() == "Hello, world!"); } #endif } From 4402176df5e1aec1c77b19f973b4575c7e526dcd Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 20:52:57 +0100 Subject: [PATCH 08/11] :white_check_mark: add regression test --- test/src/unit-regression2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/unit-regression2.cpp b/test/src/unit-regression2.cpp index 86320f039..1e8c4922a 100644 --- a/test/src/unit-regression2.cpp +++ b/test/src/unit-regression2.cpp @@ -495,7 +495,7 @@ TEST_CASE("regression tests 2") const char DATA[] = R"("Hello, world!")"; const auto s = std::as_bytes(std::span(DATA)); json j = json::parse(s); - CHECK(j.dump() == "Hello, world!"); + CHECK(j.dump() == "\"Hello, world!\""); } #endif } From c886646707b14e8919216e7d90d5ea6c9ffa6e2b Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 21:04:41 +0100 Subject: [PATCH 09/11] :rotating_light: fix warning --- test/src/unit-udt_macro.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/src/unit-udt_macro.cpp b/test/src/unit-udt_macro.cpp index b56a5d15e..a13ac006b 100644 --- a/test/src/unit-udt_macro.cpp +++ b/test/src/unit-udt_macro.cpp @@ -106,7 +106,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_without_private_data_2, age, name, met class person_with_private_alphabet { public: - bool operator==(const person_with_private_alphabet& other) + bool operator==(const person_with_private_alphabet& other) const { return a == other.a && b == other.b && @@ -169,7 +169,7 @@ class person_with_private_alphabet class person_with_public_alphabet { public: - bool operator==(const person_with_public_alphabet& other) + bool operator==(const person_with_public_alphabet& other) const { return a == other.a && b == other.b && From bdb2469c313cb8b83bfc0de9a1e789e93379ff00 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 21:36:30 +0100 Subject: [PATCH 10/11] :rotating_light: fix warnings --- Makefile | 2 + .../nlohmann/detail/input/input_adapters.hpp | 19 ++-- .../nlohmann/detail/iterators/iter_impl.hpp | 63 +++++--------- single_include/nlohmann/json.hpp | 86 ++++++++----------- test/src/unit-conversions.cpp | 8 ++ 5 files changed, 76 insertions(+), 102 deletions(-) diff --git a/Makefile b/Makefile index 0b9aa8213..d3963f503 100644 --- a/Makefile +++ b/Makefile @@ -84,6 +84,7 @@ doctest: # -Wno-missing-prototypes: for NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE # -Wno-padded: padding is nothing to warn about # -Wno-range-loop-analysis: items tests "for(const auto i...)" +# -Wno-extra-semi-stmt: spurious warnings for semicolons after JSON_ASSERT() # -Wno-switch-enum -Wno-covered-switch-default: pedantic/contradicting warnings about switches # -Wno-weak-vtables: exception class is defined inline, but has virtual method pedantic_clang: @@ -100,6 +101,7 @@ pedantic_clang: -Wno-missing-prototypes \ -Wno-padded \ -Wno-range-loop-analysis \ + -Wno-extra-semi-stmt \ -Wno-switch-enum -Wno-covered-switch-default \ -Wno-weak-vtables" cmake -S . -B cmake-build-pedantic -GNinja -DCMAKE_BUILD_TYPE=Debug -DJSON_MultipleHeaders=ON -DJSON_BuildTests=On cmake --build cmake-build-pedantic diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index eed370fd2..a78a6ec96 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -374,7 +374,8 @@ typename iterator_input_adapter_factory::adapter_type input_adapte // Enables ADL on begin(container) and end(container) // Encloses the using declarations in namespace for not to leak them to outside scope -namespace container_input_adapter_factory_impl { +namespace container_input_adapter_factory_impl +{ using std::begin; using std::end; @@ -384,15 +385,15 @@ struct container_input_adapter_factory {}; template struct container_input_adapter_factory< ContainerType, - void_t()), end(std::declval()))> > -{ - using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); + void_t()), end(std::declval()))>> + { + using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); - static adapter_type create(const ContainerType& container) - { - return input_adapter(begin(container), end(container)); - } -}; + static adapter_type create(const ContainerType& container) +{ + return input_adapter(begin(container), end(container)); +} + }; } diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp index 6c65c6018..67134166e 100644 --- a/include/nlohmann/detail/iterators/iter_impl.hpp +++ b/include/nlohmann/detail/iterators/iter_impl.hpp @@ -38,8 +38,10 @@ This class implements a both iterators (iterator and const_iterator) for the template class iter_impl { + /// the iterator with BasicJsonType of different const-ness + using other_iter_impl = iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; /// allow basic_json to access private members - friend iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; + friend other_iter_impl; friend BasicJsonType; friend iteration_proxy; friend iteration_proxy_value; @@ -390,33 +392,11 @@ class iter_impl } /*! - @brief comparison: equal + @brief comparison: equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - bool operator==(const iter_impl& other) const - { - // if objects are not the same, the comparison is undefined - if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) - { - JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); - } - - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - return (m_it.object_iterator == other.m_it.object_iterator); - - case value_t::array: - return (m_it.array_iterator == other.m_it.array_iterator); - - default: - return (m_it.primitive_iterator == other.m_it.primitive_iterator); - } - } - - bool operator==(const iter_impl::type>& other) const + template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > + bool operator==(const IterImpl& other) const { // if objects are not the same, the comparison is undefined if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) @@ -440,16 +420,17 @@ class iter_impl } /*! - @brief comparison: not equal + @brief comparison: not equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - bool operator!=(const iter_impl& other) const + template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > + bool operator!=(const IterImpl& other) const { return !operator==(other); } /*! - @brief comparison: smaller + @brief comparison: smaller @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator<(const iter_impl& other) const @@ -476,7 +457,7 @@ class iter_impl } /*! - @brief comparison: less than or equal + @brief comparison: less than or equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator<=(const iter_impl& other) const @@ -485,7 +466,7 @@ class iter_impl } /*! - @brief comparison: greater than + @brief comparison: greater than @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator>(const iter_impl& other) const @@ -494,7 +475,7 @@ class iter_impl } /*! - @brief comparison: greater than or equal + @brief comparison: greater than or equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator>=(const iter_impl& other) const @@ -503,7 +484,7 @@ class iter_impl } /*! - @brief add to iterator + @brief add to iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl& operator+=(difference_type i) @@ -532,7 +513,7 @@ class iter_impl } /*! - @brief subtract from iterator + @brief subtract from iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl& operator-=(difference_type i) @@ -541,7 +522,7 @@ class iter_impl } /*! - @brief add to iterator + @brief add to iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl operator+(difference_type i) const @@ -552,7 +533,7 @@ class iter_impl } /*! - @brief addition of distance and iterator + @brief addition of distance and iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ friend iter_impl operator+(difference_type i, const iter_impl& it) @@ -563,7 +544,7 @@ class iter_impl } /*! - @brief subtract from iterator + @brief subtract from iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl operator-(difference_type i) const @@ -574,7 +555,7 @@ class iter_impl } /*! - @brief return difference + @brief return difference @pre The iterator is initialized; i.e. `m_object != nullptr`. */ difference_type operator-(const iter_impl& other) const @@ -595,7 +576,7 @@ class iter_impl } /*! - @brief access to successor + @brief access to successor @pre The iterator is initialized; i.e. `m_object != nullptr`. */ reference operator[](difference_type n) const @@ -626,7 +607,7 @@ class iter_impl } /*! - @brief return the key of an object iterator + @brief return the key of an object iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ const typename object_t::key_type& key() const @@ -642,7 +623,7 @@ class iter_impl } /*! - @brief return the value of an iterator + @brief return the value of an iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ reference value() const diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index ac0568ce9..8b6344f92 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -5186,7 +5186,8 @@ typename iterator_input_adapter_factory::adapter_type input_adapte // Enables ADL on begin(container) and end(container) // Encloses the using declarations in namespace for not to leak them to outside scope -namespace container_input_adapter_factory_impl { +namespace container_input_adapter_factory_impl +{ using std::begin; using std::end; @@ -5196,15 +5197,15 @@ struct container_input_adapter_factory {}; template struct container_input_adapter_factory< ContainerType, - void_t()), end(std::declval()))> > -{ - using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); + void_t()), end(std::declval()))>> + { + using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); - static adapter_type create(const ContainerType& container) - { - return input_adapter(begin(container), end(container)); - } -}; + static adapter_type create(const ContainerType& container) +{ + return input_adapter(begin(container), end(container)); +} + }; } @@ -10924,8 +10925,10 @@ This class implements a both iterators (iterator and const_iterator) for the template class iter_impl { + /// the iterator with BasicJsonType of different const-ness + using other_iter_impl = iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; /// allow basic_json to access private members - friend iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; + friend other_iter_impl; friend BasicJsonType; friend iteration_proxy; friend iteration_proxy_value; @@ -11276,33 +11279,11 @@ class iter_impl } /*! - @brief comparison: equal + @brief comparison: equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - bool operator==(const iter_impl& other) const - { - // if objects are not the same, the comparison is undefined - if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) - { - JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); - } - - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - return (m_it.object_iterator == other.m_it.object_iterator); - - case value_t::array: - return (m_it.array_iterator == other.m_it.array_iterator); - - default: - return (m_it.primitive_iterator == other.m_it.primitive_iterator); - } - } - - bool operator==(const iter_impl::type>& other) const + template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > + bool operator==(const IterImpl& other) const { // if objects are not the same, the comparison is undefined if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) @@ -11326,16 +11307,17 @@ class iter_impl } /*! - @brief comparison: not equal + @brief comparison: not equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ - bool operator!=(const iter_impl& other) const + template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > + bool operator!=(const IterImpl& other) const { return !operator==(other); } /*! - @brief comparison: smaller + @brief comparison: smaller @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator<(const iter_impl& other) const @@ -11362,7 +11344,7 @@ class iter_impl } /*! - @brief comparison: less than or equal + @brief comparison: less than or equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator<=(const iter_impl& other) const @@ -11371,7 +11353,7 @@ class iter_impl } /*! - @brief comparison: greater than + @brief comparison: greater than @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator>(const iter_impl& other) const @@ -11380,7 +11362,7 @@ class iter_impl } /*! - @brief comparison: greater than or equal + @brief comparison: greater than or equal @pre The iterator is initialized; i.e. `m_object != nullptr`. */ bool operator>=(const iter_impl& other) const @@ -11389,7 +11371,7 @@ class iter_impl } /*! - @brief add to iterator + @brief add to iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl& operator+=(difference_type i) @@ -11418,7 +11400,7 @@ class iter_impl } /*! - @brief subtract from iterator + @brief subtract from iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl& operator-=(difference_type i) @@ -11427,7 +11409,7 @@ class iter_impl } /*! - @brief add to iterator + @brief add to iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl operator+(difference_type i) const @@ -11438,7 +11420,7 @@ class iter_impl } /*! - @brief addition of distance and iterator + @brief addition of distance and iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ friend iter_impl operator+(difference_type i, const iter_impl& it) @@ -11449,7 +11431,7 @@ class iter_impl } /*! - @brief subtract from iterator + @brief subtract from iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ iter_impl operator-(difference_type i) const @@ -11460,7 +11442,7 @@ class iter_impl } /*! - @brief return difference + @brief return difference @pre The iterator is initialized; i.e. `m_object != nullptr`. */ difference_type operator-(const iter_impl& other) const @@ -11481,7 +11463,7 @@ class iter_impl } /*! - @brief access to successor + @brief access to successor @pre The iterator is initialized; i.e. `m_object != nullptr`. */ reference operator[](difference_type n) const @@ -11512,7 +11494,7 @@ class iter_impl } /*! - @brief return the key of an object iterator + @brief return the key of an object iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ const typename object_t::key_type& key() const @@ -11528,7 +11510,7 @@ class iter_impl } /*! - @brief return the value of an iterator + @brief return the value of an iterator @pre The iterator is initialized; i.e. `m_object != nullptr`. */ reference value() const @@ -16845,7 +16827,7 @@ class basic_json detail::parser_callback_tcb = nullptr, const bool allow_exceptions = true, const bool ignore_comments = false - ) + ) { return ::nlohmann::detail::parser(std::move(adapter), std::move(cb), allow_exceptions, ignore_comments); @@ -25390,7 +25372,7 @@ template<> inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( is_nothrow_move_constructible::value&& is_nothrow_move_assignable::value -) + ) { j1.swap(j2); } diff --git a/test/src/unit-conversions.cpp b/test/src/unit-conversions.cpp index 16c4f798e..7f59c63ec 100644 --- a/test/src/unit-conversions.cpp +++ b/test/src/unit-conversions.cpp @@ -1702,3 +1702,11 @@ TEST_CASE("JSON to enum mapping") CHECK(TS_INVALID == json("what?").get()); } } + +#ifdef JSON_HAS_CPP_17 + #undef JSON_HAS_CPP_17 +#endif + +#ifdef JSON_HAS_CPP_14 + #undef JSON_HAS_CPP_14 +#endif From fc7e181cbf38c041b875723a0194626e31c52430 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 29 Dec 2020 22:21:31 +0100 Subject: [PATCH 11/11] :alembic: fix string representation --- test/src/unit-class_parser.cpp | 2 +- test/src/unit-regression1.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/src/unit-class_parser.cpp b/test/src/unit-class_parser.cpp index c612daabc..2df07d6d4 100644 --- a/test/src/unit-class_parser.cpp +++ b/test/src/unit-class_parser.cpp @@ -509,7 +509,7 @@ TEST_CASE("parser class") CHECK(parser_helper("\"€\"").get() == "€"); CHECK(parser_helper("\"🎈\"").get() == "🎈"); - CHECK(parser_helper("\"\\ud80c\\udc60\"").get() == "\U00013060"); + CHECK(parser_helper("\"\\ud80c\\udc60\"").get() == "\xf0\x93\x81\xa0"); CHECK(parser_helper("\"\\ud83c\\udf1e\"").get() == "🌞"); } } diff --git a/test/src/unit-regression1.cpp b/test/src/unit-regression1.cpp index f5520056f..df660ddb4 100644 --- a/test/src/unit-regression1.cpp +++ b/test/src/unit-regression1.cpp @@ -400,7 +400,7 @@ TEST_CASE("regression tests 1") SECTION("issue #146 - character following a surrogate pair is skipped") { - CHECK(json::parse("\"\\ud80c\\udc60abc\"").get() == "\U00013060abc"); + CHECK(json::parse("\"\\ud80c\\udc60abc\"").get() == "\xf0\x93\x81\xa0\x61\x62\x63"); } SECTION("issue #171 - Cannot index by key of type static constexpr const char*")